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 > && invocation.Arguments[] 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 == )
{
e.Instance = proxyGenerator.CreateInterfaceProxyWithTarget(serviceWithTypes[], e.Instance, types);
} }
catch (Exception ex)
{ }
});
}

5.对于wcf服务无法调用控制器的拦截器(ActionFilter),所以可以调用该服务时就自动实现了拦截

6.下一步改进,在EnableAop()里可以无需传入类型参数,而代替的是IInterceptor[] 参数

7.如果可以实现特性就更优雅了

[原创]Aop之使用Autofac+Castle 自动注入服务且动态代理服务实现拦截(非MVC控制器拦截)的更多相关文章

  1. 在ASP.Net Core下,Autofac实现自动注入

    之前使用以来注入的时候,都是在xml配置对应的接口和实现类,经常会出现忘了写配置,导致注入不生效,会报错,而且项目中使用的是SPA的模式,ajax报错也不容易看出问题,经常会去排查日志找问题. 于是在 ...

  2. netcore 2.2 使用 Autofac 实现自动注入

    Autofac自动注入是通过名称约定来实现依赖注入 ps:本demo接口层都以“I”开头,以“Service”结尾.服务层实现都以“Service”结尾. 为什么要实现自动注入 大多时候,我们都是 以 ...

  3. 五)Spring + Quartz 复杂业务的两个问题:获取Spring上下文 和 自动注入服务类

    配置如下: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:// ...

  4. Quartz.Net 与 Autofac 自动注入 的整合问题

    一.问题发现 今天早上在用 Quartz.Net 做定时扫描异常队列的功能模块时,发现处理异常队列的Job里面的ILog对象服务,Autofac没有自动注入进来. 然后在网上查阅相关资料,无奈发现 Q ...

  5. [Solution] AOP原理解析及Castle、Autofac、Unity框架使用

    本节目录: AOP介绍 AOP基本原理 AOP框架 Castle Core Castle Windsor Autofac Unity AOP介绍 面向切面编程(Aspect Oriented Prog ...

  6. AOP原理解析及Castle、Autofac、Unity框架使用

    转自:https://www.cnblogs.com/neverc/p/5241466.html AOP介绍 面向切面编程(Aspect Oriented Programming,英文缩写为AOP), ...

  7. 自己实现简单的AOP(五)使Demo适应webApi、亦可完成属性自动注入

    在前文的Demo中,webApi的Controller是不能自动注入的,原因是 IHttpController 和 IController 是通过两个不同的途径进行激活的. IHttpControll ...

  8. ASP.NET MVC Autofac自动注入

    依赖注入容器有很多插件,我用过Unity和Autofac,这两个插件给我最明显的感觉就是Autofac很快,非常的快,毕竟是第三方开发的,而Unity相对而言性能比较稳定 下面附上Autofac自动注 ...

  9. Autofac手动注入及自动注入示例

    参考:http://www.cnblogs.com/xinchuang/archive/2013/05/07/3065433.html#2911661 一.环境 vs2012.mvc4..Net Fr ...

随机推荐

  1. Docker学习笔记_安装ActiveMQ

    一.实验环境 1.宿主机OS:Win10 64位 2.虚拟机OS:Ubuntu18.04,虚拟机名称:Ubuntu18VM1,虚拟机IP:192.168.8.25 3.操作账号 :Docker 4.在 ...

  2. RocketMq2

  3. PyV8在服务端运行自动崩溃问题

    近来想在服务端架设WSGI + PyV8去自动解析JavaScript代码,然后返回解析后的数据给客户端.但是发现,在nginx配置后,客户端一请求,服务端的python脚本自动崩溃. 见代码: de ...

  4. delphi TString使用(取有规律的字符串中某一项内容)

    {目的,取得下面字符串中的每一项内容,如s:='a,b,c,d',要去的用逗号隔开的每一项内容这时采用Tstring,会方便很多,TString是继承TStringList带有List所有属性.} v ...

  5. C# 常用正则验证[转]

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  6. 【EfF】 贪婪加载和延迟加载 (virtual去掉关闭延迟加载)

    EntityFramework(EF)贪婪加载和延迟加载的选择和使用 贪婪加载:顾名思议就是把所有要加载的东西一 次性读取 1 using (var context = new MyDbContext ...

  7. angular 新建组件

    创建组件 ng g component componentName 第一步:引入其他组件 ngFor指令与数据绑定(数据驱动视图) 父组件穿值到自组建

  8. Sqlserver风格规范

    常见的字段类型选择 1.字符类型建议采用varchar/nvarchar数据类型 2.金额货币建议采用money数据类型 3.科学计数建议采用numeric数据类型 4.自增长标识建议采用bigint ...

  9. MySql8.0后密码认证方式问题[caching-sha2-password]

    这个问题通常在laravel中表现为类似下边的异常: local.ERROR: SQLSTATE[HY000] [2006] MySQL server has gone away {"exc ...

  10. 说一下我认识的*nix下的服务器热重启

    步骤: 第一: 收到SIGTERM以后现在的服务器监听socket停止accept 但是并没有停止listen,这个很关键.(所以客户端发起的tcp连接的syn得不到synack,只是继续等待,而不会 ...