有没有办法在不使用属性decoraction的情况下将AOP应用于.NET库?

时间:2014-09-09 04:15:01

标签: c# .net aop event-sourcing

我完全理解我的问题很奇怪,可能会有很多更好的方法来实现我的目标,所以任何帮助都会受到赞赏。

基本思想是跟踪在运行时对某些类型的实体的某些属性所做的所有更改,而不修改其代码。

假设我有一个名为Foo的实体,如下所述:

class Foo
{
    private string _bar;
    public string Bar 
    { 
        get { return _bar; } 
        set 
        {
            // some logic here...
            _bar = value;
            // some logic here... 
        }
    }
}

基本上我想要一个允许我编写如下代码的库:

Hook.For<Foo>()
    .OnSet(foo => foo.Bar)
    .Action((foo, value) => 
    {
        // save the state of the foo instance along with the value passed to the setter
    });

我知道所需的功能涉及添加一些额外的构建步骤来修改输出程序集IL代码。没有必要让语法流畅,我甚至不介意JSON或XML配置。主要思想不是改变应用程序的大量遗留代码,而是使用外部监视(出于调试目的)。

是否有任何AOP框架可以全局应用这样的方面,而不需要我用属性来装饰每个属性或类?

2 个答案:

答案 0 :(得分:2)

看起来PostSharp提供了在现有代码上应用外部方面的功能,如下文所述:http://programmersunlimited.wordpress.com/2011/07/27/applying-aspects-to-3rd-party-assemblies-using-postsharp/

我现在要使用这个解决方案。

答案 1 :(得分:1)

您可能还想看一下GitHub上的Tyler Brinks SNAP项目:https://github.com/TylerBrinks/Snap

该框架位于任意数量的IoC容器之上,可以在您的类之上注入AOP代理:

 // Configure SNAP to look at all assemblies starting with the "ConsoleApplication1"  namespace.
// Next, tell SNAP to intercept any code decorated with a DemoLoggingAttribute by running
// an instance of the DemoLoggingInterceptor class.
SnapConfiguration.For<StructureMapAspectContainer>(c =>
    {
        // Tell SNAP to only be concerned with stuff starting with this namespace.
        c.IncludeNamespace("ConsoleApplication1*");
        // Tell SNAP to intercept any method or class decorated with    "DemoLoggingAttribute"
        // by wrapping execution in your own DemoInterceptor class.
        c.Bind<DemoLoggingInterceptor>().To<DemoLoggingAttribute>();
    });

  // Configure StructureMap as usual.
  ObjectFactory.Configure(c => c.For<ISampleClass>().Use<SampleClass>());



 // Use your own class to handle interception.  Logging is a good example.
 public class DemoLoggingInterceptor : MethodInterceptor
 {
     public override void InterceptMethod(IInvocation invocation, MethodBase method, Attribute attribute)
     {
     // Log something important here.

     // Then continue executing your method.
     invocation.Proceed();
     }
 }