应用AOP简化WinForm的异步操作——Spring.NET实现
2011-12-25 22:43
441 查看
此篇狗尾续狗,有炒现饭之嫌。但为了学习Spring.NET的AOP实现,同时也是响应前篇的读者,还是再选这个例子。这不,CCTV6又在放《失恋33天》,咱还写这个。
Advice(通知)
Spring.NET 使用标记接口 AopAlliance.Aop.IAdvice 来定义通知,这个接口又有四个直接的派生接口,还有两个间接地派生接口。
Spring.Aop.IAfterReturningAdvice,定义方法执行之后的通知,通知的方法名为 AfterReturning
Spring.Aop.IBeforeAdvice,定义所有的前置通知,还是一个标记接口
Spring.Aop.IMethodBeforeAdvice,方法的前置通知接口,通知的方法名称为 Before
AopAlliance.Intercept.IInterceptor, 环绕通知的接口,也是一个标记接口
AopAlliance.Intercept.IMethodInterceptor,方法的环绕通知接口,Invoke 是调用方法。
我们要用到的是IMethodInterceptor
Attribute
UI:MVP模式
View接口:
Proxy(代理)
Configuration(配置)
Advice(通知)
Spring.NET 使用标记接口 AopAlliance.Aop.IAdvice 来定义通知,这个接口又有四个直接的派生接口,还有两个间接地派生接口。
Spring.Aop.IAfterReturningAdvice,定义方法执行之后的通知,通知的方法名为 AfterReturning
Spring.Aop.IBeforeAdvice,定义所有的前置通知,还是一个标记接口
Spring.Aop.IMethodBeforeAdvice,方法的前置通知接口,通知的方法名称为 Before
AopAlliance.Intercept.IInterceptor, 环绕通知的接口,也是一个标记接口
AopAlliance.Intercept.IMethodInterceptor,方法的环绕通知接口,Invoke 是调用方法。
我们要用到的是IMethodInterceptor
class WorkThreadAdvice : IWorkThreadHandler, IMethodInterceptor { private IBlockDialog blockForm; private bool reportProgress; private BackgroundWorker worker; private object returnValue; public WorkThreadAdvice(bool reportProgress) { this.reportProgress = reportProgress; } #region Implementation of IWorkThreadHandler void worker_DoWork(object sender, DoWorkEventArgs e) { var args = e.Argument as IMethodInvocation; returnValue = args.Proceed(); } void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { blockForm.ShowProcess(e.ProgressPercentage); } void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (blockForm != null) { blockForm.UnBlock(); } } public void ReportProgress(int percentage) { worker.ReportProgress(percentage); } #endregion #region Implementation of IMethodInterceptor public object Invoke(IMethodInvocation invocation) { worker = new BackgroundWorker(); worker.DoWork += new DoWorkEventHandler(worker_DoWork); worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); if (reportProgress) { worker.WorkerReportsProgress = true; worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged); } worker.RunWorkerAsync(invocation); blockForm = invocation.Target as IBlockDialog; if (blockForm != null) { blockForm.Handler = this; blockForm.Block(); } while (worker.IsBusy) { Thread.Sleep(500); } return returnValue; } #endregion }
Attribute
public class WorkThreadAttribute : AopAttributeBase { private readonly bool reportProgress; public WorkThreadAttribute(bool reportProgress) { this.reportProgress = reportProgress; } public WorkThreadAttribute() : this(false) { } public override IAdvice CreateAdvice() { return new WorkThreadAdvice(reportProgress); } }
UI:MVP模式
View接口:
public interface IArticleView { List<ArticleModel> Articles { set; } }
Persenter接口:
Spring.NET被拦截的类不能像PIAB那样继承MarshalByRefObject,必须实现一个接口
public interface IArticlePresenter : IAsyncPresenter { void Download(); IArticleView View { get; set; } }
View实现:WinForm
public partial class ArticleForm : BaseView, IArticleView { #region Constants and Fields private readonly IArticlePresenter presenter; #endregion #region Constructors and Destructors public ArticleForm() { this.InitializeComponent(); this.presenter = PresenterLoader.LoadPresenter<IArticlePresenter>(); this.presenter.View = this; } #endregion #region Methods protected override void OnShown(EventArgs e) { this.presenter.Download(); } #endregion #region Implementation of IArticleView private List<ArticleModel> articles; public List<ArticleModel> Articles { set; } #endregion }
Presenter实现:
public class ArticlePresenter : AsyncPresenterBase,IArticlePresenter { private List<ArticleModel> articles; #region Implementation of IAsyncPresenter [WorkThread] public void Download() { articles = ArticleModel.GetAll(); Thread.Sleep(3000); } public IArticleView View { get; set; } protected override void Binding() { View.Articles = articles; } #endregion }
Proxy(代理)
PIAB生成代理对象很方便:PolicyInjection.Create
Spring.NET没有如此简便的方法,但可以通过ProxyFactory来生成Proxy,同时加入自定义AOP相关的Attribute的逻辑即可
class PresenterLoader { public static T LoadPresenter<T>() where T : IAsyncPresenter { var context = ContextRegistry.GetContext(); var sourceObject = (T)context.GetObject(typeof(T).Name.Substring(1),typeof(T)); var factory = new ProxyFactory(sourceObject); var sourceObjectType = sourceObject.GetType(); var methodInfos = sourceObjectType.GetMethods(); foreach (MethodInfo methodInfo in methodInfos) { var attributes = methodInfo.GetCustomAttributes(false); foreach (object attribute in attributes) { if (attribute is AopAttributeBase) { var pointcutAttribute = attribute as AopAttributeBase; var advice = pointcutAttribute.CreateAdvice(); var advisor = new AttributeMatchMethodPointcutAdvisor { Advice = advice, Attribute = attribute.GetType() }; factory.AddAdvisor(advisor); } } } var obj = (T)factory.GetProxy(); return obj; } }
Configuration(配置)
使用过Spring.NET IoC的都知道
<?xml version="1.0"?> <configuration> <configSections> <sectionGroup name="spring"> <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" /> <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /> </sectionGroup> </configSections> <spring> <context> <resource uri="config://spring/objects"/> </context> <objects xmlns="http://www.springframework.net" > <object id="ArticlePresenter" type="WinFormPractice.Presenters.ArticlePresenter" /> </objects> </spring> </configuration>
好了,Spring.NET之AOP研究告一段落。项目中咱还是用的EntLib,马上准备升级EntLib5。不过,Spring.NET的IoC和配置还是很强大的。
相关文章推荐
- 应用AOP简化WinForm的异步操作——EntLib PIAB实现
- 应用AOP简化WinForm的异步操作——PostSharp实现
- 一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-复杂业务的实现(商品入库)-附案例操作视
- 一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-复杂业务的实现(商品入库)-附案例操作视频
- Microsoft .NET Framework 2.0对文件传输协议(FTP)操作(异步上传,下载等)实现汇总2
- Spring AOP 实现原理与 CGLIB 应用
- 基于Couchbase和Spring.Net AOP的分布式缓存实现
- AOP技术应用和研究--SpringAop实现原理
- 一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-演示ORM对象与DataGridView的绑定技术-商品字典的另一个实现
- spring的AOP实现记录操作日志
- Spring+Mybatis 实现aop数据库读写分离与多数据库源配置操作
- 一个通过BackgroundWorker实现WinForm异步操作的例子
- Spring的AOP实现日志管理操作
- Spring AOP 实现原理与 CGLIB 应用
- Spring AOP 实现系统操作日志记录
- springMVC +Mybatis +spring aop 实现用户系统操作日志记录
- [置顶] Redis应用3-基于Redis消息队列实现的异步操作
- Spring AOP 实现原理与 CGLIB 应用
- 在ASP.NET Core中使用AOP来简化缓存操作
- Spring--Spring AOP 实现原理与 CGLIB 应用