问题描述
我想要一个像这样的属性来处理横切关注点,比如 Logging , Exception , ...
I want to have an attribute like this for Cross Cutting Concerns like Logging , Exception , ...
public class MyService
{
[Log] // Interception (AOP)
[ExceptionHandler] // Interception (AOP)
public void DoSomething()
{
}
}
我知道我可以用 postsharp 编写这些代码,但我想用免费的库(如 Castle Core 和 ...
I know that I can write these codes with postsharp but I want to write these interceptions with free libraries like Castle Core and ...
任何人都可以帮助我并为此目的编写示例吗???我需要一个非常简单的样本来学习概念
Can anyone help me and write a sample for these purpose ???I need a very simple sample for learning concepts
推荐答案
Autofac 是一个免费的 IoC 容器.我使用 Autofac 和 Autofac.Extras.DynamicProxy2 nuget, 文档.
Autofac is a free IoC container. I use Autofac with Autofac.Extras.DynamicProxy2 nuget, docs.
假设您知道为什么以及何时(和不)使用拦截器,并且您想拦截某些功能:
Assuming you know why and when to (and not to) use interceptors, and you want to intercept some functionality:
public class FooService : IFooService
{
public void MoreFoo()
{
DoSomething();
}
public void LessFoo()
{
DoSomethingElse();
}
}
它需要连线".我喜欢属性,因为您不需要在 IoC 容器接线中明确指定拦截器.您只需指定一个要注意的属性:
It needs to be "wired". I like attributes as you don't need to explicitly specify the interceptor at IoC container wiring. You just specify an attribute to watch out for:
[Intercept(typeof(Logger)]
public class FooService : IFooService { ... }
并接线:
var builder = new ContainerBuilder();
builder.RegisterType<FooService>()
.EnableClassInterceptors();
然后在另一个文件中创建您的 Logger 拦截器:
Then create your Logger interceptor in another file:
class Logger : IInterceptor
{
public void Intercept(IInvocation invocation) // implements the IInterceptor interface
{
_loggerService.Log("calling " + invocation.Method.Name);
invocation.Proceed();
_loggerService.Log("finished " + invocation.Method.Name);
}
}
如您所见,您可以创建计时器、try-catch 块等等.数据库上下文和其他一次性资源很有趣:
As you can see, you can create timers, try-catch blocks, and much more. Database context and other disposable resources is an interesting one:
class Logger : IInterceptor
{
public void Intercept(IInvocation invocation) // implements the IInterceptor interface
{
using (var someThing = new SomeResource())
{
invocation.Proceed();
}
}
}
通常对于这样的资源,您需要在方法中使用 someThing.这是另一个问题的主题!(请参阅 invocation.SetArgumentValue 或 invocation.TargetType.GetProperties() 以与封闭类进行通信.我对此不是 100% 满意,因此其他人的一些评论会有所帮助)
Usually with such a resource you need to use someThing inside your method. That's a topic for another question! (see invocation.SetArgumentValue or invocation.TargetType.GetProperties() to communicate to the enclosing class. I'm not 100% comfortable with this, so some comments from others would be helpful)
那么,以日志为例:
void ManageFoo()
{
// sorry for the messy code, what else can I do?!
_logger("more foo please");
_fooService.MoreFoo();
_logger("less foo please");
_fooService.LessFoo();
_logger("enough foo");
}
ManageFoo 方法的实际关注点在所有混乱的日志记录中都消失了(添加安全性和其他问题,您最终可能会遇到大麻烦).
The actual concern of the ManageFoo method is lost in all the mess of logging (add security and other concerns and you can end up with a big mess).
现在你可以像这样重写它:
Now you can rewrite it like this:
void ManageFoo()
{
_fooService.MoreFoo();
_fooService.LessFoo();
}
这篇关于如何使用 Castle Core 或其他库(只是免费库)为横切关注点编写拦截器(AOP)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!