您的位置:首页 > 运维架构

Autofac整合Castle.DynamicProxy实现AOP

2013-01-10 22:11 736 查看
1.官网的例子有一些问题。自己学习总结下并且重新打包一个版本供学习。

 

1.AttributedInterfaceInterceptionFixture

[TestFixture]
public class AttributedInterfaceInterceptionFixture
{
[Intercept(typeof(AddOneInterceptor))]
public interface IHasI
{
int GetI();
}

public class C : IHasI
{
public int I { get; private set; }

public C()
{
I = 10;
}

public int GetI()
{
return I;
}
}

class AddOneInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
invocation.Proceed();
if (invocation.Method.Name == "GetI")
invocation.ReturnValue = 1 + (int)invocation.ReturnValue;
}
}

[Test]
public void DetectsNonInterfaceServices()
{
var builder = new ContainerBuilder();
builder.RegisterType<C>().EnableInterfaceInterceptors();
builder.RegisterType<AddOneInterceptor>();
var c = builder.Build();
var dx = Assert.Throws<DependencyResolutionException>(() => c.Resolve<C>());
Assert.IsInstanceOf<InvalidOperationException>(dx.InnerException);
}

[Test]
public void FindsInterceptionAttributeOnReflectionComponent()
{
var builder = new ContainerBuilder();
builder.RegisterType<C>().As<IHasI>().EnableInterfaceInterceptors();
builder.RegisterType<AddOneInterceptor>();
var cpt = builder.Build().Resolve<IHasI>();

Assert.AreEqual(11, cpt.GetI()); // proxied
}

[Test]
public void FindsInterceptionAttributeOnExpressionComponent()
{
var builder = new ContainerBuilder();
builder.Register(c => new C()).As<IHasI>().EnableInterfaceInterceptors();
builder.RegisterType<AddOneInterceptor>();
var cpt = builder.Build().Resolve<IHasI>();

Assert.AreEqual(11, cpt.GetI()); // proxied
}
}


 

2.ClassInterceptorsFixture

[TestFixture]
public class ClassInterceptorsFixture
{
[Intercept(typeof(AddOneInterceptor))]
public class C
{
public int I { get; set; }

public C(int i)
{
I = i;
}

public virtual int GetI()
{
return I;
}
}

class AddOneInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
invocation.Proceed();
if (invocation.Method.Name == "GetI")
invocation.ReturnValue = 1 + (int)invocation.ReturnValue;
}
}

[Test]
public void InterceptsReflectionBasedComponent()
{
var builder = new ContainerBuilder();
builder.RegisterType<C>().EnableClassInterceptors();
builder.RegisterType<AddOneInterceptor>();
var container = builder.Build();
var i = 10;
var c = container.Resolve<C>(TypedParameter.From(i));
var got = c.GetI();
Assert.AreEqual(i + 1, got);
}
}


 

3.InterceptorsChosenByMetadataFixture

 

[TestFixture]
public class InterceptorsChosenByMetadataFixture
{
public interface ICustomerService
{
int GetVisitCount();
}

public class CustomerService : ICustomerService
{
int VisitCount { get; set; }

public CustomerService()
{
VisitCount = 10;
}

public int GetVisitCount()
{
return VisitCount;
}
}

class AddOneInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
invocation.Proceed();
if (invocation.Method.Name.StartsWith("Get"))
invocation.ReturnValue = 1 + (int)invocation.ReturnValue;
}
}

[Test]
public void InterceptsWhenUsingExtendedPropertyAndType()
{
var builder = new ContainerBuilder();
builder.RegisterType<CustomerService>()
.As<ICustomerService>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(AddOneInterceptor));
builder.RegisterType<AddOneInterceptor>();
var container = builder.Build();
var cs = container.Resolve<ICustomerService>();
Assert.AreEqual(11, cs.GetVisitCount());
}
}


 

4.InterfaceInterceptorsFixture

[TestFixture]
public class InterfaceInterceptorsFixture
{
[Test(Description = "Interception should not be able to occur against internal interfaces.")]
public void DoesNotInterceptInternalInterfaces()
{
// DynamicProxy2 only supports visible interfaces so internal won't work.
var builder = new ContainerBuilder();
builder.RegisterType<StringMethodInterceptor>();
builder
.RegisterType<Interceptable>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(StringMethodInterceptor))
.As<IInternalInterface>();
var container = builder.Build();
var dre = Assert.Throws<DependencyResolutionException>(() => container.Resolve<IInternalInterface>());
Assert.IsInstanceOf<InvalidOperationException>(dre.InnerException, "The inner exception should explain about public interfaces being required.");
}

[Test(Description = "Interception should be able to occur against public interfaces.")]
public void InterceptsPublicInterfaces()
{
var builder = new ContainerBuilder();
builder.RegisterType<StringMethodInterceptor>();
builder
.RegisterType<Interceptable>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(StringMethodInterceptor))
.As<IPublicInterface>();
var container = builder.Build();
var obj = container.Resolve<IPublicInterface>();
Assert.AreEqual("intercepted-PublicMethod", obj.PublicMethod(), "The interface method should have been intercepted.");
}

public class Interceptable : IPublicInterface, IInternalInterface
{
public string PublicMethod()
{
throw new NotImplementedException();
}

public string InternalMethod()
{
throw new NotImplementedException();
}
}

public interface IPublicInterface
{
string PublicMethod();
}

internal interface IInternalInterface
{
string InternalMethod();
}

private class StringMethodInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (invocation.Method.ReturnType == typeof(string))
{
invocation.ReturnValue = "intercepted-" + invocation.Method.Name;
}
else
{
invocation.Proceed();
}
}
}

}


 

代码下载: AopDemo

 

总结: 相对于spring.net繁琐的API和大量XML, Autofac&DynamicProxy 提供了又一种轻量级IOC&AOP解决方案。要说不足的地方。 与当前主流技术(如WCF,MVC,ORM)整合稍弱一些(也有可能可以很好整合,只是官方Demo没有给出。需要进一步去学习)。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: