[原创]Aop之使用Autofac+Castle 自动注入服务且动态代理服务实现拦截(非MVC控制器拦截)
public static class AutofacComponentManualRegister { /// <summary> /// 注册 /// </summary> /// <param name="builder">bundles</param> public static IContainer RegisterIOC() { ContainerBuilder builder = new ContainerBuilder(); //构造函数注入 builder.RegisterAssemblyTypes(Assembly.GetCallingAssembly()).AsImplementedInterfaces(); //注入控制器并实现属性注入 builder.RegisterControllers(Assembly.GetCallingAssembly()); //支持过滤器的属性注入- builder.RegisterFilterProvider(); builder.RegisterType<MemoryCacheProvider>().As<ICacheProvider>().SingleInstance(); builder.RegisterType<AppService>().As<IAppService>().EnableAop(typeof(IAppService)); builder.RegisterType<ProductService>().As<IProductService>().SingleInstance(); builder.RegisterType<CustomerService>().As<ICustomerService>().SingleInstance(); builder.RegisterType<UserService>().As<IUserService>().SingleInstance(); var registration = builder.RegisterType<SaleOrderService>().As<ISaleOrderService>().SingleInstance(); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); return container; } private static void EnableAop<TLimit, TActivatorData, TSingleRegistrationStyle>(this IRegistrationBuilder<TLimit, TActivatorData, TSingleRegistrationStyle> registrationBuilder,Type type) { registrationBuilder.RegistrationData.ActivatingHandlers.Add((sender, e) => { try { e.Instance = proxyGenerator.CreateInterfaceProxyWithTarget(type, e.Instance, new LogInterceptor()); } catch (Exception ex) { } }); } static readonly ProxyGenerator proxyGenerator = new ProxyGenerator(); }
2.拦截类
public class LogInterceptor : IInterceptor { /// <summary> /// logger /// </summary> private static readonly ILog Logger = LogManager.GetLogger(typeof(LogInterceptor)); public LogInterceptor() { } public void Intercept(IInvocation invocation) { var request = JsonConvert.SerializeObject(invocation.Arguments); if (invocation.Arguments.Length > 0 && invocation.Arguments[0] is Request) { Logger.DebugFormat("请求服务名:{0} 方法名:{1} 请求参数:{2}", invocation.TargetType, invocation.Method.Name, request); invocation.Proceed(); var resp = invocation.ReturnValue; var response = JsonConvert.SerializeObject(resp); Logger.DebugFormat("请求服务名:{0} 方法名:{1} 返回参数:{2}", invocation.TargetType, invocation.Method.Name, response); } else { invocation.Proceed(); Logger.ErrorFormat("非法请求:{0}",request); } } }
3.
/// <summary> /// IAppService /// </summary> [ServiceContract] public interface IAppService { /// <summary> /// APP后端获取标接口 /// </summary> /// <returns></returns> [OperationContract] IsAliveResp IsAlive(IsAliveReq req); }
4.
public class AppService : IAppService { #region field /// <summary> /// IBatis访问DB接口 /// </summary> private readonly ISqlMapper _mapper; /// <summary> /// logger /// </summary> private static readonly ILog Logger = LogManager.GetLogger(typeof(AppService)); #endregion #region .ctor /// <summary> /// App服务接口(对App端) /// </summary> public AppService() { this._mapper = SqlMap.Instance(); } #endregion #region public /// <summary> /// 获取商品列表 /// </summary> /// <returns></returns> public IsAliveResp IsAlive(IsAliveResp req) { var result = this._mapper.QueryForObject<DateTime>("queryCurrentTimeFromDatabase", null); return new IsAliveResp() { Success = true, Time = result.ToString("yyyy-MM-dd HH:mm:ss.fff") }; } }
对EnableAop改进,支持自动获取相应的接口类,并传入拦截器数组
private static void EnableAop<TLimit, TActivatorData, TSingleRegistrationStyle>(this IRegistrationBuilder<TLimit, TActivatorData, TSingleRegistrationStyle> registrationBuilder,params IInterceptor[] types) { registrationBuilder.RegistrationData.ActivatingHandlers.Add((sender, e) => { try { var serviceWithTypes = e.Component.Services.OfType<IServiceWithType>().Select(x => x.ServiceType).ToList(); if (serviceWithTypes.Count == 1) { e.Instance = proxyGenerator.CreateInterfaceProxyWithTarget(serviceWithTypes[0], e.Instance, types); } } catch (Exception ex) { } }); }
5.对于wcf服务无法调用控制器的拦截器(ActionFilter),所以可以调用该服务时就自动实现了拦截
6.下一步改进,在EnableAop()里可以无需传入类型参数,而代替的是IInterceptor[] 参数
7.如果可以实现特性就更优雅了