zoukankan      html  css  js  c++  java
  • 我学MEF系列(8):MEF+Unity实现可扩展拦截器

    前言

    MEF很好的解决了扩展性问题,但本身不具有拦截器的功能,但是我们在应用程序中为了权限控制,日志记录等,却又需要拦截(AOP)器功能,本文主要介绍使用MEF+Unity实现可扩展的拦截器,使得我们的应用程序既具有可扩展性,又能实现拦截。

    先决条件

    1. 你需要了解MEF和Unity Framework的基本知识;

    2. 下载MEF Contrib (点击这里下载),MEF Contrib提供了支持Unity的拦截器扩展:CompositionIntegration;

    3. 下载Unity Application Block DLLs,点击这里下载;

    有了这些dll,我们就可以实现我们的MEF+Unity Interception。

    工作原理

    image

    上图中的Unity + MEF Integration Layer ,是一个中间层,由MEFContrib中的MefContrib.Integration.Unity.dll实现。它使得MEF组件可以自动注入到Unity组件中,反之,Unity组件也可注入到MEF组件中。这便使得我们的程序可以同时使用MEF和Unity并发挥他们各自的优势。

    实现

    1.新建项目MEFWithUnityInterceptionDemo,新建目录RefenceLib,将上面下载的dll拷贝到该目录中,并添加Unity和MEFContrib相关dll的引用。

    image

    2.添加ILogger接口及其实现类ConsoleLogger,并将ConsoleLogger标记为导出:

     1 /// <summary>
    2 /// 日志接口
    3 /// </summary>
    4 public interface ILogger
    5 {
    6 void Write(string message);
    7 }
    8
    9 /// <summary>
    10 /// Logger,导出类型为ILogger
    11 /// </summary>
    12 [Export(typeof(ILogger))]
    13 public class ConsoleLogger : ILogger
    14 {
    15 public void Write(string message)
    16 {
    17 Console.WriteLine(message);
    18 }
    19 }

    3.定义拦截器Interceptor,并定义导入类型为ILogger的导入。自定义拦截器using命名空间:Microsoft.Practices.Unity.InterceptionExtension,并实现IInterceptionBehavior。这是实现对Logger的方法拦截很重要的一步。

     1 /// <summary> 
    2 /// 自定义拦截器
    3 /// </summary>
    4 public class Interceptor : IInterceptionBehavior
    5 {
    6 /// <summary>
    7 /// 导入日志对象
    8 /// </summary>
    9 [Import]
    10 public ILogger Logger { get; set; }
    11
    12 public Interceptor()
    13 {
    14 }
    15
    16 public IEnumerable<Type> GetRequiredInterfaces()
    17 {
    18 return Type.EmptyTypes;
    19 }
    20
    21 public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
    22 {
    23 IMethodReturn msg = null;
    24 //方法调用前
    25 Logger.Write("Hello World + Pre Calling");
    26
    27 // 方法调用
    28 msg = getNext()(input, getNext);
    29
    30 //调用后
    31 Logger.Write("Hello World + Post Calling");
    32
    33 return msg;
    34 }
    35
    36 /// <summary>
    37 /// 指定是否拦截
    38 /// </summary>
    39 public bool WillExecute
    40 {
    41 get
    42 {
    43 return true;
    44 }
    45 }
    46 }

    对自定义拦截器的几点说明:

    a.WillExecute属性指定是否需要拦截,这里默认返回true,

    b.在Invork方法中实现拦截后需要执行的相关处理;

    c.代码"msg = getNext()(input, getNext);"可以调用到被拦截的真实方法,在它的前后我们处理拦截逻辑。

    4.添加接口IApplication及其实现类Application。Application负责创建MEF容器并组合。对ILogger方法调用是在这里触发的。而且这里的方法调用,我们希望可以被前面定义的拦截器捕获到,已证明我们的拦截器有作用。

    View Code
     1     /// <summary>
    2 /// IApplication接口
    3 /// </summary>
    4 public interface IApplication
    5 {
    6 void Run();
    7 }
    8 /// <summary>
    9 /// Application
    10 /// </summary>
    11 public class Application : IApplication
    12 {
    13 [Import]
    14 public ILogger Logger { get; set; }
    15
    16 public Application()
    17 {}
    18
    19 /// <summary>
    20 /// 请注意这里的虚方法
    21 /// </summary>
    22 public virtual void Run()
    23 {
    24 //创建目录
    25 var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
    26 //创建组合容器
    27 var container = new CompositionContainer(catalog);
    28 //组合部件
    29 container.ComposeParts(this);
    30 //调用方法
    31 Logger.Write("Helloworld");
    32 }
    33 }

    5.在program中创建Unity容器,并添加MEF和Unity的中间层扩展CompositionIntegration,并将拦截器的Catalog加入到CompositionIntegration的组合目录中,实现拦截器中部件成功组合。具体实现如下,代码中有注释:

     1            // 创建unity容器
    2 var unityContainer = new UnityContainer();
    3 var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
    4
    5 //注册MefContrib提供拦截扩展
    6 unityContainer.AddNewExtension<CompositionIntegration>();
    7 //注册自定义的拦截器扩展
    8 unityContainer.AddNewExtension<Interception>();
    9
    10 //在unity容器中注册类型,并指定拦截虚方法,指定拦截器为Interceptor
    11 unityContainer.RegisterType<IApplication, Application>(new Interceptor<VirtualMethodInterceptor>(), new InterceptionBehavior<Interceptor>());
    12
    13 //配置MefContrib提供的组合拦截器
    14 CompositionIntegration integration = unityContainer.Configure<CompositionIntegration>();
    15 //指定需要组合的目录
    16 integration.Catalogs.Add(assemblyCatalog);
    17
    18 //从容器中获取Application的实例
    19 IApplication app = unityContainer.Resolve<Application>();
    20
    21 app.Run();
    22
    23 Console.ReadLine();

    至此我们实现了利用MEF和Unity实现一个可扩展的拦截器功能。运行效果如下:

     image

    最终代码结构如下:

    image

    示例源码下载地址:MEFWithUnityInterceptionDemo.7z

    本文主要参考:http://www.dotnetspark.com/kb/4659-mef--unity-interception.aspx

  • 相关阅读:
    node学习笔记
    mysql开发常用小结
    MS SQL 合并结果集并求和 分类: SQL Server 数据库 2015-02-13 10:59 93人阅读 评论(0) 收藏
    MS SQL 合并结果集并求和 分类: SQL Server 数据库 2015-02-13 10:59 92人阅读 评论(0) 收藏
    正是孤独让你变得出众,而不是合群 分类: 其他 2015-02-08 20:38 83人阅读 评论(0) 收藏
    正是孤独让你变得出众,而不是合群 分类: 其他 2015-02-08 20:38 82人阅读 评论(0) 收藏
    Jquery easy UI 上中下三栏布局 分类: ASP.NET 2015-02-06 09:19 370人阅读 评论(0) 收藏
    Jquery easy UI 上中下三栏布局 分类: ASP.NET 2015-02-06 09:19 368人阅读 评论(0) 收藏
    过年为什么要贴门神? 分类: 其他 2015-01-31 09:53 131人阅读 评论(0) 收藏
    过年为什么要贴门神? 分类: 其他 2015-01-31 09:53 130人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/pszw/p/2298744.html
Copyright © 2011-2022 走看看