想要通过方法拦截,实现Audit功能,IoC容器采用的是Autofac,在其官方文档上找到了拦截器相关的帮助:http://docs.autofac.org/en/latest/advanced/interceptors.html
在nuget中引用Autofac.Extras.DynamicProxy2后,提示Autofac的DLL找不到,然后在nuget中升级Autofac,不报错了,但是没有成功拦截方法。
ILogger和实现:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; //using Autofac.Extras.DynamicProxy2; namespace HiAutofac { public interface ILogger { void WriteLine(String line); } //[Intercept(typeof(TestInterceptor))] public class DefaultLogger : ILogger { public void WriteLine(string line) { Console.WriteLine("Default Logger : {0}", line); } } }
TestInterceptor实现:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Castle.DynamicProxy; namespace HiAutofac { public class TestInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine("Interceptor"); } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Autofac; using Autofac.Extras.DynamicProxy2; //using Autofac.Extras.DynamicProxy2; namespace HiAutofac { class Program { static void Main(string[] args) { var builder = new ContainerBuilder(); builder .RegisterType<DefaultLogger>() .As<ILogger>() .EnableInterfaceInterceptors(); builder.RegisterType<TestInterceptor>(); var container = builder.Build(); using (var scope = container.BeginLifetimeScope()) { var logger = scope.Resolve<ILogger>(); logger.WriteLine("Hello World"); } Console.ReadLine(); } } }
以上就是全部代码,运行后Hello World输出,但是拦截器没有执行。求大神指导,或者提供一个可以使用的Demo,谢谢。
在群里大神的帮助下终于还是搞成功了。
有两种方式可以搞定:
1:将[Intercept(typeof(TestInterceptor))]特性加在public interface ILogger定义中。
2:在代码中处理:
var builder = new ContainerBuilder(); builder .RegisterType<DefaultLogger>() .EnableInterfaceInterceptors() .InterceptedBy(typeof(TestInterceptor)) .As<ILogger>(); builder.RegisterType<TestInterceptor>();
第一种方法没有效果啊,只有第二种方法有效果
我来晚了
官网原文,用第一种方法必须是 visible方法
Tips
Use Public Interfaces
Interface interception requires the interface be public (or, at least, visible to the dynamically generated proxy assembly). Non-public interface types can’t be intercepted.
If you want to proxy internal interfaces, you must mark the assembly containing the interface with [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")].
Use Virtual Methods
Class interception requires the methods being intercepted to be virtual since it uses subclassing as the proxy technique.