当前位置: 移动技术网 > IT编程>开发语言>.net > Asp.Net Core轻量级Aop解决方案:AspectCore

Asp.Net Core轻量级Aop解决方案:AspectCore

2017年12月08日  | 移动技术网IT编程  | 我要评论

女士旅行箱,超级衙内txt,edd-202

什么是aspectcore project ?

aspectcore project 是适用于asp.net core 平台的轻量级 aop(aspect-oriented programming) 解决方案,它更好的遵循asp.net core的模块化开发理念,使用aspectcore可以更容易构建低耦合、易扩展的web应用程序。aspectcore使用emit实现高效的动态代理从而不依赖任何第三方aop库。

开使使用aspectcore

启动 visual studio。从 file 菜单, 选择 new > project。选择 asp.net core web application 项目模版,创建新的 asp.net core web application 项目。

  • 从 nuget 安装 aspectcore.extensions.dependencyinjection package:
  • pm>   install-package aspectcore.extensions.dependencyinjection
  • 在一般情况下可以使用抽象的interceptorattribute自定义特性类,它实现iinterceptor接口。aspectcore默认实现了基于attribute的拦截器配置。我们的自定义拦截器看起来像下面这样:
public class custominterceptorattribute : interceptorattribute
{
  public async override task invoke(iaspectcontext context, aspectdelegate next)
  {
    try
    {
      console.writeline("before service call");
      await next(context);
    }
    catch (exception)
    {
      console.writeline("service threw an exception!");
      throw;
    }
    finally
    {
      console.writeline("after service call");
    }
   }
 }

定义icustomservice接口和它的实现类customservice:

public interface icustomservice
{
  [custominterceptor]
  void call();
}
public class customservice : icustomservice
{
  public void call()
  {
    console.writeline("service calling...");
  }
}

在homecontroller中注入icustomservice:

public class homecontroller : controller
{
  private readonly icustomservice _service;
  public homecontroller(icustomservice service)
  {
    _service = service;
  }
  public iactionresult index()
  {
    _service.call();
    return view();
  }
}

注册icustomservice,接着,在configureservices中配置创建代理类型的容器:

public iserviceprovider configureservices(iservicecollection services)
{
  services.addtransient<icustomservice, customservice>();
  services.addmvc();
  services.addaspectcore();
  return services.buildaspectcoreserviceprovider();
}

拦截器配置。首先安装aspectcore.extensions.configuration package:

pm> install-package aspectcore.extensions.configuration

全局拦截器。使用addaspectcore(action<aspectcoreoptions>)的重载方法,其中aspectcoreoptions提供interceptorfactories注册全局拦截器:

 services.addaspectcore(config =>
 {
   config.interceptorfactories.addtyped<custominterceptorattribute>();
 });

带构造器参数的全局拦截器,在custominterceptorattribute中添加带参数的构造器:

public class custominterceptorattribute : interceptorattribute
{
  private readonly string _name;
  public custominterceptorattribute(string name)
  {
    _name = name;
  }
  public async override task invoke(aspectcontext context, aspectdelegate next)
  {
    try
    {
      console.writeline("before service call");
      await next(context);
    }
    catch (exception)
    {
      console.writeline("service threw an exception!");
      throw;
    }
    finally
    {
      console.writeline("after service call");
    }
  }
}

修改全局拦截器注册:

services.addaspectcore(config =>
{
   config.interceptorfactories.addtyped<custominterceptorattribute>(args: new object[] { "custom" });
});

作为服务的全局拦截器。在configureservices中添加:

services.addtransient<custominterceptorattribute>(provider => new custominterceptorattribute("service"));

修改全局拦截器注册:

services.addaspectcore(config =>
{
  config.interceptorfactories.addserviced<custominterceptorattribute>();
});

作用于特定service或method的全局拦截器,下面的代码演示了作用于带有service后缀的类的全局拦截器:

services.addaspectcore(config =>
{
  config.interceptorfactories.addtyped<custominterceptorattribute>(method => method.declaringtype.name.endswith("service"));
});

使用通配符的特定全局拦截器:

services.addaspectcore(config =>
{
  config.interceptorfactories.addtyped<custominterceptorattribute>(predicatefactory.forservice("*service"));
});

在aspectcore中提供nonaspectattribute来使得service或method不被代理:

[nonaspect]
public interface icustomservice
{
  void call();
}

同时支持全局忽略配置,亦支持通配符:

 services.addaspectcore(config =>
 {
   //app1命名空间下的service不会被代理
   config.nonaspectoptions.addnamespace("app1");
   //最后一级为app1的命名空间下的service不会被代理
   config.nonaspectoptions.addnamespace("*.app1");
   //icustomservice接口不会被代理
   config.nonaspectoptions.addservice("icustomservice");
   //后缀为service的接口和类不会被代理
   config.nonaspectoptions.addservice("*service");
   //命名为query的方法不会被代理
   config.nonaspectoptions.addmethod("query");
   //后缀为query的方法不会被代理
   config.nonaspectoptions.addmethod("*query");
 });

拦截器中的依赖注入。在拦截器中支持属性注入,构造器注入和服务定位器模式。
属性注入,在拦截器中拥有public get and set权限的属性标记[aspectcore.abstractions.fromservices](区别于microsoft.aspnetcore.mvc.fromservices)特性,即可自动注入该属性,如:

public class custominterceptorattribute : interceptorattribute
{
  [aspectcore.abstractions.fromservices]
  public ilogger<custominterceptorattribute> logger { get; set; }
  public override task invoke(aspectcontext context, aspectdelegate next)
  {
    logger.loginformation("call interceptor");
    return next(context);
  }
}

构造器注入需要使拦截器作为service,除全局拦截器外,仍可使用serviceinterceptor使拦截器从di中激活:

public interface icustomservice
{
  [serviceinterceptor(typeof(custominterceptorattribute))]
  void call();
}

服务定位器模式。拦截器上下文aspectcontext可以获取当前scoped的serviceprovider:

public class custominterceptorattribute : interceptorattribute
{
  public override task invoke(aspectcontext context, aspectdelegate next)
  {
    var logger = context.serviceprovider.getservice<ilogger<custominterceptorattribute>>();
    logger.loginformation("call interceptor");
    return next(context);
  }
}

使用autofac和aspectcore。aspectcore原生支持集成autofac,我们需要安装下面两个nuget packages:

pm> install-package autofac.extensions.dependencyinjection
pm> install-package aspectcore.extensions.autofac

aspectcore提供registeraspectcore扩展方法在autofac的container中注册动态代理需要的服务,并提供asinterfacesproxy和asclassproxy扩展方法启用interface和class的代理。修改configureservices方法为:

public iserviceprovider configureservices(iservicecollection services)
{
  services.addmvc();
  var container = new containerbuilder();
  container.registeraspectcore();
  container.populate(services);
  container.registertype<customservice>().as<icustomservice>().instanceperdependency().asinterfacesproxy();

  return new autofacserviceprovider(container.build());
}

有问题反馈

如果您有任何问题,请提交 issue 给我们。

aspectcore project 项目地址:

以上所述是小编给大家介绍的asp.net core轻量级aop解决方案:aspectcore,希望对大家有所帮助

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网