MEF是微软的一个ioc框架,使用非常方便,我们只需要在需要导出的类上标记[Export],在需要使用的地方[import]就可以使用了。现在我们扩展MEF,在其装配生成实例时,使用Castle DynamicProxy对其生成透明代理。
我们先实现一个拦截器,并且继承Attribute基类,这个我们可以将这个拦截器作为类的特性来使用。

using Castle.DynamicProxy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MefAopTest
{
public class LogInterceptor : Attribute,IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("begin");
invocation.Proceed();
Console.WriteLine("end");
}
}
}

这个拦截器中,我们对拦截的方法执行前和执行后都增加了操作。

然后我们新增一个类,这个类使我们需要导出的类。

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
namespace MefAopTest
{
[Export(typeof(ClassA))]
[LogInterceptor]
public class ClassA
{
public virtual void GetA()
{
Console.WriteLine("GetA");
}
}
}

在这个类上,我们增加特性 [Export(typeof(ClassA))],这是MEF的基本用法。[LogInterceptor]是我们定义的拦截器,我们可以拦截GetA方法。需要拦截的方法必须是虚方法。

下面我们来扩展下MEF。
ExportProvider 类:检索与指定的 ImportDefinition 对象相匹配的导出。这个类的作用很明确,就是用来寻找与 ImportDefinition 对象匹配的ExportDefinition。
我们新增一个基础自ExportProvider 的类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using Castle.DynamicProxy;
namespace MefAopTest
{
public class AOPExportProvider : ExportProvider, IDisposable
{
private CatalogExportProvider _exportProvider; public AOPExportProvider(Func<ComposablePartCatalog> catalogResolver)
{
_exportProvider = new CatalogExportProvider(catalogResolver());
} public ExportProvider SourceProvider
{
get
{
return _exportProvider.SourceProvider;
}
set
{
_exportProvider.SourceProvider = value;
}
} protected override IEnumerable<Export> GetExportsCore(
ImportDefinition definition, AtomicComposition atomicComposition)
{
IEnumerable<Export> exports = _exportProvider.GetExports(definition, atomicComposition);
return exports.Select(export => new Export(export.Definition, () => GetValue(export)));
} private object GetValue(Export innerExport)
{
object value = innerExport.Value; Type t = value.GetType();
IInterceptor[] attribs = t.GetCustomAttributes(typeof(IInterceptor), true).Cast<IInterceptor>().ToArray(); ProxyGenerator generator = new ProxyGenerator();
object proxy = generator.CreateClassProxy(value.GetType(), attribs);
return proxy;
} public void Dispose()
{
_exportProvider.Dispose();
}
}
}

在装配时,会触发GetExportsCore方法,去寻找相对应的导出。我们在GetValue方法中,使用Castle生成动态代理。

IInterceptor[] attribs = t.GetCustomAttributes(typeof(IInterceptor), true).Cast<IInterceptor>().ToArray();

上面这行代码主要是从需要导出的类的自定义特性中,寻找拦截器。我们这里定义的是[LogInterceptor]。
然后我们再生成透明的动态代理

ProxyGenerator generator = new ProxyGenerator();
object proxy = generator.CreateClassProxy(value.GetType(), attribs);

下面我们新增一个窗体类,窗体上有一个按钮,点击按钮,触发ClassA实例的GetA方法。看是否可以进行拦截。

namespace MefAopTest
{
public : Form
{
public Form1()
{
InitializeComponent();
ComposeParts();
}
[Import(typeof(ClassA))]
private ClassA c1; public void ComposeParts()
{
Func<ComposablePartCatalog> catalogResolver = () =>
{ var catalog = new AggregateCatalog();
AssemblyCatalog assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); catalog.Catalogs.Add(assemblyCatalog);
return catalog;
}; AOPExportProvider provider = new AOPExportProvider(catalogResolver);
CompositionContainer container = new CompositionContainer(provider);
provider.SourceProvider = container;
container.ComposeParts(this);
} private void Test_Click(object sender, EventArgs e)
{
c1.GetA();
}
}
}

在代理里,我们定义了一个字段,用来Import ClassA类。

[Import(typeof(ClassA))]
private ClassA c1;

在我们装配代码中,使用我们扩展的AopExportProvider

 
image.png

我们测试下,点击按钮,看看输出的情况。

 
image.png

好的,我们成功的拦截了ClassA的GetA方法,并在方法执行前和执行后都增加了操作。
这种AOP的实现,我们只需要在需要导出的类上增加一个特性就行了。如果有其他需求,我们可以再增加拦截器,并在相应的类上增加特性就行了,很方便。美中不足的是,需要按照MEF的方式去生成实例,不能像postsharp那样。

使用MEF与Castle实现AOP的更多相关文章

  1. 使用dynamic和MEF实现轻量级的AOP组件 ---- 系列文章

      .NET 4 实践 - 使用dynamic 和MEF实现轻量级的AOP组件(1)   .NET 4 实践 - 使用dynamic和MEF实现轻量级的AOP组件 (2) .NET 4 实践 - 使用 ...

  2. [AOP系列]Autofac+Castle实现AOP事务

    一.前言 最近公司新项目,需要搭架构进行开发,其中需要保证事务的一致性,经过一番查找,发现很多博文都是通过Spring.Net.Unity.PostSharp.Castle Windsor这些方式实现 ...

  3. [AOP系列]Autofac+Castle实现AOP日志

    一.前言 最近公司新项目,需要搭架构进行开发,其中需要对一些日志进行输出,经过一番查找,发现很多博文都是通过Spring.Net.Unity.PostSharp.Castle Windsor这些方式实 ...

  4. C#使用Castle实现AOP面向切面编程

    Castle.Core 本质是创建继承原来类的代理类,重写虚方法实现AOP功能.个人觉得比Autofac用着爽 使用方式比较简单,先新建一个控制台项目,然后在Nuget上搜索Castle.Core并安 ...

  5. 使用dynamic和MEF实现轻量级的AOP组件 (3)

    转摘 https://www.cnblogs.com/niceWk/archive/2010/07/22/1783068.html 水到渠成 在上一篇的<偷梁换柱>中,介绍了Weavabl ...

  6. 使用dynamic和MEF实现轻量级的AOP组件 (2)

    转摘 https://www.cnblogs.com/niceWk/archive/2010/07/21/1782092.html 偷梁换柱 上一篇我们初试了DynamicAspect这把小刀,如果你 ...

  7. 使用 Castle 实现 AOP,以及 Autofac 集成 Castle

    Castle 是 2003 年诞生于 Apache Avalon 项目,目的是为了创建一个IOC 框架.发展到现在已经有四个组件: ORM组件:ActiveRecord IOC组件:Windsor 动 ...

  8. .NET 4 实践 - 使用dynamic和MEF实现轻量级的AOP组件 (4)

    转摘 https://www.cnblogs.com/niceWk/archive/2010/07/23/1783394.html 借花献佛 前面我们介绍了构成DynamicAspect绝大部分的类, ...

  9. 使用dynamic 和MEF实现轻量级的 AOP 组件 (1)

    转载https://www.cnblogs.com/niceWk/archive/2010/07/19/1780843.html AOP魔法 今天你AOP了吗?谈到AOP,总有一种神秘的感觉,人类对于 ...

随机推荐

  1. 如何搭建hibernate框架

    我写这篇博客,主要是想让大家能够快速上手hibernate,本人建议学习框架,应该一个框架一个框架学习,别一上手就三大框架整合,学习之类的.这里只是单独搭建hibernate框架,让大家 能够更好的上 ...

  2. vs2013和vs2010的配置

    win10下vs2013和vs2010的相关配置 ------made by siwuxie095 主要是推荐一些vs2013和vs2010的好用的插件和配色方案,下面主要是以vs2013示例 1.首 ...

  3. virtualbox Linux与Windows共享文件

    安装virtualbox增强功能 在Windows下新建文件用于共享,点设置->共享文件夹->添加共享文件,制定路径和名称(名称用于Linux中挂载使用)(选择固定分配) 在Linux中m ...

  4. Course Schedule课程表12(用Topological Sorting)

    [抄题]: 现在你总共有 n 门课需要选,记为 0 到 n - 1.一些课程在修之前需要先修另外的一些课程,比如要学习课程 0 你需要先学习课程 1 ,表示为[0,1]给定n门课以及他们的先决条件,判 ...

  5. 练习并熟练掌握交互式 SQL 语言

    哈工大数据库系统 实验:练习并熟练掌握交互式 SQL 语言   实验目的:基于给定的 OrderDB 数据库, 练习并熟练掌握交互式 SQL 语言实验环境:sql sever 2008 附:Order ...

  6. type="image"提交表单

    <input type="image" style="cursor:pointer; ">

  7. SQL0973N在 "<堆名>" 堆中没有足够的存储器可用来处理语句

    SQL0973N在 "<堆名>" 堆中没有足够的存储器可用来处理语句. 解释: 已使用此堆的所有可用内存.不能处理该语句. 用户响应: 接收到此消息(SQLCODE)后 ...

  8. 2018.10.01 NOIP模拟 卡牌游戏(贪心)

    传送门 简单贪心题. 然而考试的时候失了智少讨论了一种情况导致gg. 实际上用到了二分图匹配的思想,L每次找到刚好比当前的牌小一点的出出去,看能匹配几个. 如何处理? 我们先考虑第一种比分策略. 我们 ...

  9. Unit Testing of Spring MVC

    试验1:做的条目不发现首先,我们必须确保我们的应用是工作性质所做条目不发现.我们可以写的测试以确保通过以下步骤: 1.配置的模拟对象时抛出一个todonotfoundexception findbyi ...

  10. pyhthon 求GPA平均学分绩点

    #coding=utf-8 ''' 北大4.0 成绩 学分 100-90 4.0 89-85 3.7 84-82 3.3 81-78 3.0 77-75 2.7 74-72 2.3 71-68 2.0 ...