前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >dotnetcore实现Aop

dotnetcore实现Aop

原创
作者头像
HueiFeng
修改2020-02-12 14:48:01
5650
修改2020-02-12 14:48:01
举报
文章被收录于专栏:HueiFeng技术专栏HueiFeng技术专栏

<h1>dotnetcore实现Aop</h1>

<pre><code> Aop大家都不陌生,然而今天给大家不将讲官方的filter,今天给大家分享一个轻量级的Aop解决方案(AspectCore)

</code></pre>

<h2>什么是AspectCore</h2>

<p>AspectCore是一个面向切面编程,基于.NetCore和.NetFramwork的扩平台框架,对方法拦截器、依赖项注入集成、web应用程序、数据验证等提供核心支持。</p>

<h2>AspectCore基本特性</h2>

<ul>

<li>

<p>提供抽象的Aop接口,基于该接口可以轻松的使用自己的代理类实现替换默认的实现.</p>

</li>

<li>

<p>框架不包含IoC,也不依赖具体IoC实现,可以使用Asp.Net Core的内置依赖注入或者任何兼容Asp.Net Core的第三方Ioc来继承AspectCore到Asp.NetCore应用中</p>

</li>

<li>

<p>高性能的异步拦截系统</p>

</li>

<li>

<p>灵活的配置系统</p>

</li>

<li>

<p>基于service的而非基于实现类的切面构造</p>

</li>

<li>

<p>支持扩平台的Asp.Net Core环境</p>

</li>

</ul>

<h2>使用AspectCore</h2>

<p>从NuGet中安装AspectCore</p>

<pre><code data-language="c" class="lang-c">AspectCore.Extensions.DependencyInjection

</code></pre>

<p>package</p>

<pre><code>PM&gt; Install-package AspectCore.Extensions.DependencyInjection

</code></pre>

<p>下面我创建了一个Api应用程序.</p>

<p>NuGet安装</p>

<pre><code>AspectCore.Configuration

</code></pre>

<p>package</p>

<pre><code>PM&gt; Install-package AspectCore.Configuration

</code></pre>

<p>下面我新建了一个拦截器 CustomInterceptorAttribute,继承AbstractInterceptorAttribute(一般情况下继承他即可),他实现IInterceptor接口AspectCore默认实现了基于<code data-backticks="1">Attribute</code>的拦截器配置。</p>

<pre><code data-language="c#" class="lang-c#">/// &lt;summary&gt;

/// 自定义拦截器

/// </summary>

public class CustomInterceptorAttribute : AbstractInterceptorAttribute

{

代码语言:txt
复制
/// &lt;summary&gt;
代码语言:txt
复制
///     实现抽象方法
代码语言:txt
复制
/// &lt;/summary&gt;
代码语言:txt
复制
/// &lt;param name="context"&gt;&lt;/param&gt;
代码语言:txt
复制
/// &lt;param name="next"&gt;&lt;/param&gt;
代码语言:txt
复制
public override async Task Invoke(AspectContext context, AspectDelegate next)
代码语言:txt
复制
{
代码语言:txt
复制
    try
代码语言:txt
复制
    {
代码语言:txt
复制
        Console.WriteLine("执行之前");
代码语言:txt
复制
        await next(context);//执行被拦截的方法
代码语言:txt
复制
    }
代码语言:txt
复制
    catch (Exception)
代码语言:txt
复制
    {
代码语言:txt
复制
        Console.WriteLine("被拦截的方法出现异常");
代码语言:txt
复制
        throw;
代码语言:txt
复制
    }
代码语言:txt
复制
    finally
代码语言:txt
复制
    {
代码语言:txt
复制
        Console.WriteLine("执行之后");
代码语言:txt
复制
    }
代码语言:txt
复制
}

}

</code></pre>

<p>定义<code data-backticks="1">ICustomService</code>接口和它的实现类<code data-backticks="1">CustomService</code>:</p>

<pre><code data-language="C#" class="lang-C#">public interface ICustomService

{

代码语言:txt
复制
DateTime GetDateTime();

}

public class CustomService : ICustomService

{

代码语言:txt
复制
public DateTime GetDateTime()
代码语言:txt
复制
{
代码语言:txt
复制
    return DateTime.Now;
代码语言:txt
复制
 }

}

</code></pre>

<p>在ValuesController注入ICustomService</p>

<pre><code data-language="c#" class="lang-c#">[Route("api/[controller]")]

ApiController

public class ValuesController : ControllerBase

{

代码语言:txt
复制
private readonly ICustomService _icustomserveice;
代码语言:txt
复制
public ValuesController(ICustomService icustomService) {
代码语言:txt
复制
    this._icustomserveice = icustomService;
代码语言:txt
复制
}
代码语言:txt
复制
// GET api/values
代码语言:txt
复制
[HttpGet]
代码语言:txt
复制
public DateTime Get()
代码语言:txt
复制
{
代码语言:txt
复制
    return _icustomserveice.GetDateTime();
代码语言:txt
复制
}

}

</code></pre>

<p>注册ICustomService,并创建代理容器</p>

<pre><code data-language="C#" class="lang-C#"> public IServiceProvider ConfigureServices(IServiceCollection services)

代码语言:txt
复制
    {
代码语言:txt
复制
        services.AddTransient&lt;ICustomService,CustomService&gt;();
代码语言:txt
复制
        services.AddMvc();
代码语言:txt
复制
        //全局拦截器。使用AddDynamicProxy(Action&lt;IAspectConfiguration&gt;)的重载方法,其中IAspectConfiguration提供Interceptors注册全局拦截器:
代码语言:txt
复制
        services.ConfigureDynamicProxy(config=&gt; {
代码语言:txt
复制
            config.Interceptors.AddTyped&lt;CustomInterceptorAttribute&gt;();
代码语言:txt
复制
        });
代码语言:txt
复制
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
代码语言:txt
复制
        return services.BuildAspectInjectorProvider();
代码语言:txt
复制
 }

</code></pre>

<p>作为服务的全局拦截器。在<code data-backticks="1">ConfigureServices</code>中添加:</p>

<pre><code data-language="c#" class="lang-c#">services.AddTransient&lt;CustomInterceptorAttribute&gt;(provider =&gt; new CustomInterceptorAttribute());

</code></pre>

<p>作用于特定<code data-backticks="1">Service</code>或<code data-backticks="1">Method</code>的全局拦截器,下面的代码演示了作用于带有<code data-backticks="1">Service</code>后缀的类的全局拦截器:</p>

<pre><code data-language="C#" class="lang-C#"> services.ConfigureDynamicProxy(config =&gt;

代码语言:txt
复制
        {
代码语言:txt
复制
            config.Interceptors.AddTyped&lt;CustomInterceptorAttribute&gt;(method =&gt; method.DeclaringType.Name.EndsWith("Service"));
代码语言:txt
复制
        });

</code></pre>

<p>通配符拦截器,匹配后缀为Service</p>

<pre><code data-language="C#" class="lang-C#"> services.ConfigureDynamicProxy(config =&gt;

代码语言:txt
复制
        {
代码语言:txt
复制
            config.Interceptors.AddTyped&lt;CustomInterceptorAttribute&gt;(Predicates.ForService("*Service"));
代码语言:txt
复制
        });

</code></pre>

<p>在AspectCore中提供<code data-backticks="1">NonAspectAttribute</code>来使得<code data-backticks="1">Service</code>或<code data-backticks="1">Method</code>不被代理:</p>

<pre><code data-language="C#" class="lang-C#"> [NonAspect]

代码语言:txt
复制
DateTime GetDate();

</code></pre>

<p>全局配置忽略条件</p>

<pre><code data-language="C#" class="lang-C#"> services.ConfigureDynamicProxy(config =&gt;

代码语言:txt
复制
    {
代码语言:txt
复制
        //Namespace命名空间下的Service不会被代理
代码语言:txt
复制
        config.NonAspectPredicates.AddNamespace("Namespace");
代码语言:txt
复制
        //最后一级为Namespace的命名空间下的Service不会被代理
代码语言:txt
复制
        config.NonAspectPredicates.AddNamespace("*.Namespace");
代码语言:txt
复制
        //ICustomService接口不会被代理
代码语言:txt
复制
        config.NonAspectPredicates.AddService("ICustomService");
代码语言:txt
复制
        //后缀为Service的接口和类不会被代理
代码语言:txt
复制
        config.NonAspectPredicates.AddService("*Service");
代码语言:txt
复制
        //命名为Method的方法不会被代理
代码语言:txt
复制
        config.NonAspectPredicates.AddMethod("Method");
代码语言:txt
复制
        //后缀为Method的方法不会被代理
代码语言:txt
复制
        config.NonAspectPredicates.AddMethod("*Method");
代码语言:txt
复制
    });

</code></pre>

<p>AspectCore: [https://github.com/dotnetcore/AspectCore-Framework]<br>

测试项目地址: https://github.com/fhcodegit/DotNetAspectCore/tree/master</p>

<pre><code data-backticks="4"></code></pre>

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档