您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
三六零分类信息网 > 商洛分类信息网,免费分类信息发布

浅谈AspectCore_实用技巧

2025/1/18 10:39:47发布28次查看
这篇文章主要介绍了asp.net core轻量级aop解决方案:aspectcore,需要的朋友可以参考下
什么是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()); }
以上就是浅谈aspectcore_实用技巧的详细内容。
商洛分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录