商贸营销型网站案例,php网站开发需求文档,公司网站建设服务费入什么科目,免费网页游戏网Autofac 结合 Castle DynamicProxy2 功能 Autofac 不仅作为轻量级高效的 IoC 容器#xff0c;而且还能很好的与 Castle.DynamicProxy2 结合起来#xff0c;实现 AOP 功能。 首先#xff0c;我们需要定义拦截器#xff0c;简单的定义可实现 Castle.DynamicProxy.IIntercepto… Autofac 结合 Castle DynamicProxy2 功能 Autofac 不仅作为轻量级高效的 IoC 容器而且还能很好的与 Castle.DynamicProxy2 结合起来实现 AOP 功能。 首先我们需要定义拦截器简单的定义可实现 Castle.DynamicProxy.IInterceptor 接口即可。 添加拦截器 定义好了拦截器后如何应用到相关对象呢有两种方式 1使用 Autofac.Extras.DynamicProxy2.InterceptAttribute 特性将拦截器添加到相关的类或接口上 2使用 ContainerBuilder 的 InterceptedBy() 方法在注册对象的同时添加拦截器。 如何启用拦截器呢我们只需要在 IoC 注册启用即可。启用拦截器有三种方式其中针对 WCF 比较特别下面来具体分析这几种方式的应用场景 基于接口的拦截器 在注册对象的同时启用 EnableInterfaceInterceptors() 方法。 使用接口的拦截器在使用特性 [Attribute] 注册时注册拦截器可注册到接口(Interface)上或其实现类(Implement)上。使用注册到接口上方式所有的实现类都能应用到拦截器。 对于以接口方式的注入Autofac Interceptor 要求类的方法为 public 或 virtual 即可。 示例代码 var builder new ContainerBuilder(); builder.RegisterTypeSomeType() .AsISomeInterface() .EnableInterfaceInterceptors(); builder.Register(c new CallLogger(Console.Out)); var container builder.Build(); var willBeIntercepted container.ResolveISomeInterface(); 于类的拦截器 在注册对象的同时启用 EnableClassInterceptors() 方法。 对于以类方式的注入Autofac Interceptor 要求类的方法为必须为 virtual 方法。 值得注意的是对于 子类重写override父类的虚方法时能应用到拦截器。父类可在 IoC 中注册也可不需要注册但子类必须在 IoC 中注册对于类的拦截器类都必须要注册当然拦截器也必须要注册。 示例代码 var builder new ContainerBuilder();
builder.RegisterTypeFirst().EnableClassInterceptors();
builder.Register(c new CallLogger(Console.Out)); 基于 WCF 的拦截器 WCF 是一种特殊情况。虽然 WCF Proxy 的服务对象也是一种接口但是使用 EnableInterfaceInterceptors 不会起作用因为 .NET 实际上是使用了 类似于接口行为的 System.Runtime.Remoting.TransparentProxy 。因此需要这里需要使用 InterceptTransparentProxy() 方法。 示例代码 var cb new ContainerBuilder(); cb.RegisterTypeTestServiceInterceptor(); cb.Register(c CreateChannelFactory()).SingleInstance(); cb.Register(c c.ResolveChannelFactoryITestService().CreateChannel()) .InterceptTransparentProxy(typeof(IClientChannel)) .InterceptedBy(typeof(TestServiceInterceptor)) .UseWcfSafeRelease(); 实战一下 先看看基于接口的拦截器 我们先定义一个借口名为 ICalculater using Autofac.Extras.DynamicProxy2; namespace AOP.Interceptors { //[Intercept(typeof(CalculaterInterceptor))] public interface ICalculater { int Add(int x, int y); int Sub(int x, int y); } } 然后定义该接口的实现类 Calculater using Autofac.Extras.DynamicProxy2; namespace AOP.Interceptors { //[Intercept(typeof(CalculaterInterceptor))] public class Calculater : ICalculater { public int Add(int x, int y) { return x y; } public int Sub(int x, int y) { return x - y; } } } 接下来我们来定义拦截器。这里我们定义了两个连接器通过这两个拦截器我们将能很清晰的看到拦截器是如何工作的。 定义第一个拦截器 CalculaterInterceptor using System; using Castle.DynamicProxy; namespace AOP.Interceptors { public class CalculaterInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { // 在下个拦截器或目前方法处理之前处理 var args invocation.Arguments; Console.WriteLine($Before: x{args[0]}, y{args[1]}); Console.WriteLine($Before: Method{invocation.Method.Name}); invocation.SetArgumentValue(0, 5); // handle invocation.Proceed(); // 调用下一个拦截器直到最终的目标方法。 // Post Console.WriteLine($After: TargetType{invocation.TargetType}); Console.WriteLine($After: ReturnValue{invocation.ReturnValue}); invocation.ReturnValue (int)invocation.ReturnValue - 2; } } } 定义第二个拦截器 CalculaterInterceptor2 using System; using Castle.DynamicProxy; namespace AOP.Interceptors { public class CalculaterInterceptor2 : IInterceptor { public void Intercept(IInvocation invocation) { var args invocation.Arguments; Console.WriteLine($Before2: x{args[0]}, y{args[1]}); Console.WriteLine($Before2: Method{invocation.Method.Name}); invocation.Proceed(); Console.WriteLine($After2: TargetType{invocation.TargetType}); Console.WriteLine($After2: ReturnValue{invocation.ReturnValue}); invocation.ReturnValue (int)invocation.ReturnValue - 1; // 将结果值减去 2 } } } 在 控制台 Main 函数输入我们的结果 static void Main(string[] args) { var builder new ContainerBuilder(); builder.RegisterTypeCalculater() .AsICalculater() .EnableInterfaceInterceptors() .InterceptedBy(typeof(CalculaterInterceptor), typeof(CalculaterInterceptor2)); // 这里定义了两个拦截器注意它们的顺序 builder.RegisterTypeCalculaterInterceptor(); // 注册拦截器 builder.RegisterTypeCalculaterInterceptor2(); // 注册拦截器2 var ioc builder.Build(); var calculater ioc.ResolveICalculater(); var addResult calculater.Add(2, 3); Console.WriteLine($add result: {addResult}); Console.WriteLine(-------------------); Console.ReadLine(); } 我们看看输出结果 这里我们可以看出执行顺序为 CalculaterInterceptor -- CalculaterInterceptor2 -- Target Method -- CalculaterInterceptor2 -- CalculaterInterceptor。拦截器中 invocation.Proceed() 方法用于调用下一个拦截器若存在直到最终的目标方法Target Method。不过 invocation.Proceed() 并不是一定要调用的例如对于有返回值的目标方法我们在拦截器中设置 invocation.ReturnValue 值就可正确执行这样便不会执行目标方法。在有些场景中如身份验证、缓存读取等还是特别有用的。 当然在 Main() 方法中 Ioc 注册 Caliculater 类型时我们注册了两个拦截器.InterceptedBy(typeof(CalculaterInterceptor), typeof(CalculaterInterceptor2))。我们也可以直接在 Calculater 类型 或 ICalculater 接口上以特性的形式注册如上面代码中注释掉的那部分。若是既有在类型上注册也有在 Autofac 的 Builder 中注册那么这个拦截器会重复执行。 基于类的拦截器 我们定义两个类 Flight 和其 子类 FlightOfSH public class Flight { public virtual void Fly(DateTime time) { Console.WriteLine($Flight: {time}); } } public class FlightOfSH : Flight { public override void Fly(DateTime time) { Console.WriteLine($FlightOfSH: Fly{time}); } public void Arrive(DateTime time) { Console.WriteLine($FlightOfSH: Arrive{time}); } } 这两个类的拦截器 internal class FlightInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine(Before Fly); invocation.Proceed(); Console.WriteLine(After Fly); } } 在 Main 函数中定义代码: var builder new ContainerBuilder(); builder.RegisterTypeFlight() .EnableClassInterceptors().InterceptedBy(typeof(FlightInterceptor)); builder.RegisterTypeFlightOfSH() .EnableClassInterceptors().InterceptedBy(typeof(FlightInterceptor)); builder.RegisterTypeFlightInterceptor(); var ioc builder.Build(); var flight ioc.ResolveFlight(); flight.Fly(DateTime.Now); var flightOfSH ioc.ResolveFlightOfSH(); flightOfSH.Fly(DateTime.Now); flightOfSH.Arrive(DateTime.Now); 我们看看输出结果 从输出结果中可以发现一个有趣的现在 子类 FlightOfSH 重写了 Flight 的 Fly 方法却也调用才拦截器。Arrive() 方法因为是非虚方法所有拦截器不会在该方法中调用。 当然我们这里都是直接在 Autofac 的 Ioc 注册类型时设定的也可以同上面一样使用 InterceptAttribute 特性来注入。 对于基于 WCF 的拦截器大家可以自己试验下。 总结 这里简单的介绍了 Autofac 与 Castle 动态代理功能结合来实现 AOP 功能当然Castle 本身也是个很强大的开源框架也有很强大的 IoC 功能不过我还是比较喜欢 Autofac 的 IoC 功能。 相关文章 使用 Autofac 进行依赖注入ASP.NET Core依赖注入解读使用Autofac替代实现 原文链接http://www.cnblogs.com/god--love-you/p/5699632.html .NET社区新闻深度好文微信中搜索dotNET跨平台或扫描二维码关注