在网页程序中可以透过MiddleWare来做到关注点分离,但是那是在请求中可以去拦截跟处理请求,如果今天脚色换成Service之类的程序该如何处理呢,这就是我们今天要介绍的内容AoP。
「天啊~~~我要怎麽处理每个方法的输入输出的log阿。」
一进办公室小光就听到大头的惨叫声,因为大头昨天在追一个bug追到没有方向,所以今天一大早大头决定要先把每个方法加上输入跟输出的log。
「你知道甚麽是AoP吗」
听到大头的惨叫後老K这麽问题,这时大头像找到救星一般脸上露出了曙光。
「前辈,救救我吧。」
所以今天就跟着小光还有大头了解一下甚麽是AoP以及在dotnetcore做到AoP。
AoP就是剖面导向程序设计,白话文就是如同关注点分离,对於开发的程序关注於本身的逻辑开发,而其他与本身逻辑无关的功能就从程序中抽离,然後在像切蛋糕一样切开来把额外的功能加到程序内,就如同一开始的大头在本身的程序内没有日志的功能,所以现在我们在拦截原来的程序并在这里加入日志的功能。不过说那麽多在dotnetcore内该如何处理呢,接下来我们介绍DynamicProxy这个套件。
所以我们在dotnetcore中实作AoP就是透过dynamicproxy这个套件,所以接下来我们说明如何透过autofac及dynamicproxy做到AoP。
在介绍如何撰写程序做到AoP之前先说明我们需要使用到哪些套件,接下来我们先安装以下两个套件即可。
dotnet add package Autofac.Extras.DynamicProxy
dotnet add package Autofac.Extensions.DependencyInjection
在安装完套件之後我们开始来开发AoP,首先假设我们的需求是开发一个寄送email的服务,但是我们需要输入及输出的参数,所以我们先定义介面以及实作。
public interface IEmailService
{
string Send(string message);
}
[Intercept(typeof(CallLogger))]
public class EmailService : IEmailService
{
public string Send(string message)
{
return message;
}
}
在实作时我们透过Intercept
这个属性来注入拦截者,接下来说明拦截者怎麽实作。
public class CallLogger : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine($"You are invoke {invocation.Method.Name}, args:{JsonSerializer.Serialize(invocation.Arguments)}");
invocation.Proceed();
Console.WriteLine($"You are finished {invocation.Method.Name}, result:{JsonSerializer.Serialize(invocation.ReturnValue)}");
}
}
主要拦截者就是继承IInterceptor
并实作public void Intercept(IInvocation invocation)
这个方法,这边注意invocation.Proceed();
就是执行被拦截的方法,所以我们把需要做的需求写在那方法之前跟之後即可。最後来说明如何注册拦截者跟本来的程序。
builder.Register(c => new CallLogger());
builder.RegisterType<EmailService>().As<IEmailService>().InstancePerDependency().EnableInterfaceInterceptors();
插入拦截器的方法有下列两种。
EnableClassInterceptors | 产生一个类别继承要拦截的类别,所以方法要加virtual才能拦截 |
EnableInterfaceInterceptors | 动态产生一个代理接口 |
除了透过Attribute之外,还可以在注入时加上,所以注入拦截器的方法有下列两种。
加Attribute | [Intercept(typeof(CallLogger))] |
注入拦截器 | builder.RegisterType().As().InterceptedBy(typeof(CallLogger)).InstancePerDependency().EnableInterfaceInterceptors(); |
透过AoP可以把一般物件中做到关注点分离,如此不只在处理请求中,甚至於在处理一般的函式都可以专注在该函式主要处理的逻辑上,而其它非需要关注的逻辑就抽到拦截者来处理。
在了解Media Queries的用法之前,先来了解一些RWD的观念吧。 RWD是什麽? RWD是...
使用Git管理专案,进行版本控制(version control) 剩下的27天为了预防万一,我将采...
ICE ICE(Interactive Connectivity Establishment,互动式...
Definition of a Semigroup 一个集合(Set)或称型别(Type) 有 co...
Abstract Data Type (ADT) Human - Interface - ADT L...