Caliburn笔记-方法(IMethod)的创建(wpf框架)
2009-12-25 11:44 Clingingboy 阅读(748) 评论(0) 编辑 收藏 举报为了适应框架的需要,对原生的MethodInfo进行了改造,如下图
我们可以看到,主要的功能点是允许方法可以进行异步操作.其次IMethod也继承了IMetadataContainer接口,在方法上使用元数据也非常普遍.如下为默认实现的抽象类
/// <summary> /// A base class for <see cref="IMethod"/> implementations. /// </summary> private abstract class MethodProxyBase : MetadataContainer, IMethod { private readonly MethodInfo _info; protected readonly IThreadPool _threadPool; /// <summary> /// Initializes a new instance of the <see cref="MethodProxyBase"/> class. /// </summary> /// <param name="info">The info.</param> /// <param name="threadPool">The thread pool.</param> protected MethodProxyBase(MethodInfo info, IThreadPool threadPool) { _info = info; _threadPool = threadPool; AddMetadataFrom(_info); } /// <summary> /// Gets the <see cref="MethodInfo"/> to which this instance applies. /// </summary> /// <value>The info.</value> public MethodInfo Info { get { return _info; } } /// <summary> /// Invokes the specified method on the provided instance with the given parameters. /// </summary> /// <param name="instance">The instance.</param> /// <param name="parameters">The parameters.</param> /// <returns> /// The result of the function or null if it is a procedure. /// </returns> public abstract object Invoke(object instance, params object[] parameters); /// <summary> /// Creates a background task for executing this method asynchronously. /// </summary> /// <param name="instance">The instance.</param> /// <param name="parameters">The parameters.</param> /// <returns> /// An instance of <see cref="IBackgroundTask"/>. /// </returns> public abstract IBackgroundTask CreateBackgroundTask(object instance, params object[] parameters);
关键点:
- 对方法进行了委托转换
- 方法执行安全操作,可进行抛错
- 可以进行异步
private class Function : MethodProxyBase { private readonly LateBoundFunc _theDelegate; /// <summary> /// Initializes a new instance of the <see cref="Function"/> class. /// </summary> /// <param name="info">The info.</param> /// <param name="threadPool">The thread pool.</param> public Function(MethodInfo info, IThreadPool threadPool) : base(info, threadPool) { _theDelegate = DelegateFactory.Create<LateBoundFunc>(info); } /// <summary> /// Invokes the specified method on the provided instance with the given parameters. /// </summary> /// <param name="instance">The instance.</param> /// <param name="parameters">The parameters.</param> /// <returns> /// The result of the function or null if it is a procedure. /// </returns> public override object Invoke(object instance, params object[] parameters) { return SafeInvoke(instance, parameters); } /// <summary> /// Creates a background task for executing this method asynchronously. /// </summary> /// <param name="instance">The instance.</param> /// <param name="parameters">The parameters.</param> /// <returns> /// An instance of <see cref="IBackgroundTask"/>. /// </returns> public override IBackgroundTask CreateBackgroundTask(object instance, params object[] parameters) { return new BackgroundTask(_threadPool, () => SafeInvoke(instance, parameters)); } private object SafeInvoke(object instance, object[] parameters) { try { return _theDelegate(instance, parameters); } catch(Exception) { var requirements = Info.GetParameters(); if (requirements.Length != parameters.Length) throw new CaliburnException( string.Format( "The method '{0}' expected {1} parameters but was provided {2}.", Info.Name, requirements.Length, parameters.Length) ); throw; } } }
DelegateFactory用于动态转换委托,其使用了表达式树(Expression)动态进行编译.