简体   繁体   English

从头开始创建面向方面的属性/方法

[英]Creating an Aspect Oriented Property/Method from scratch

I have one (and only one) method that I want to use an aspect on. 我有一个(也是唯一一个)我想要使用方面的方法。 It is IModule.Initialize . 它是IModule.Initialize (The method is found in about 15 classes in my solution) (该方法在我的解决方案中大约有15个类中找到)

It would look like this: 它看起来像这样:

[LogToSplashScreen]
public void Initialize()
{
   RegisterViews();
   RegisterDesignTimeVMs();
}

I would like my aspect to run this before the method body executes: 我希望我的方面在方法体执行之前运行它:

var moduleInfo = new ModuleInformation{ModuleName = "ClassNameHere"};
splashScreenService.ModuleLoadStart(moduleInformation);

And this after: 这之后:

splashScreenService.ModuleLoadEnd(moduleInformation);

Side Note: 边注:
I looked at this and thought, OK, time to try out PostSharp. 我看着这个,想,好吧,是时候试试PostSharp了。 I have heard it is the AOP tool of champions. 我听说它是​​冠军的AOP工具。 So I fired up the NuGet package (expecting to get the free version) and installed it. 所以我启动了NuGet包(希望获得免费版本)并安装它。

And it is loaded with DemoWare (ie extra installers). 它装载了DemoWare(即额外的安装程序)。 I personally don't mind. 我个人并不介意。 But I don't want my team to have to deal with an installer just so I can solve my little problem. 但我不希望我的团队必须处理安装程序,这样我才能解决我的小问题。

And demo aside, the fact that is has a UI will (I am guessing) make it hard for my build server. 除了演示之外,具有UI的事实(我猜)会使我的构建服务器变得困难。 (I use Package Restore.) (我使用Package Restore。)

These are all things I would be willing to deal with if I was going "all in" on Aspect Oriented Programming. 如果我在面向方面编程中“全力以赴”,这些都是我愿意处理的事情。
But I just need one... 但我只需要一个......


Is there a way to "roll my own" with out a lot of headache? 有没有办法“滚动自己”而不是很头疼?

I wouldn't be so quick to write off PostSharp. 我不会这么快就注销PostSharp。 You may want to post your questions/issues to the SharpCrafters forum . 您可能希望将您的问题/问题发布到SharpCrafters论坛 Your problem is a small one now, but if you come across other problems where AOP is useful, even in small quantities, a tool like PostSharp, Castle DynamicProxy, etc, can be a necessity. 你现在的问题很小,但是如果你遇到AOP有用的其他问题,即使数量很少,像PostSharp,Castle DynamicProxy等工具也是必需的。

As far as "rolling your own", what you could do is use the decorator pattern. 至于“滚动你自己”,你可以做的是使用装饰模式。 I'm not sure where the moduleInformation variable comes from, I'm going to assume you actually meant to type moduleInfo . 我不确定moduleInformation变量的来源,我假设你实际上打算输入moduleInfo

Then, assuming your interface looks something like: 然后,假设您的界面看起来像:

public interface IModule
{
    void Initialize();
}

And you have ~15 classes that implement IModule. 你有~15个实现IModule的类。 You want to add some functionality involving ModuleInformation, so create a decorator class. 您想要添加一些涉及ModuleInformation的功能,因此创建一个装饰器类。

public class ModuleDecorator : IModule
{
    IModule _subject;
    public ModuleDecorator(IModule subject)
    {
        _subject = subject;
    }

    public void Initialize()
    {
        var moduleInfo = new ModuleInformation{ModuleName = "ClassNameHere"};
        splashScreenService.ModuleLoadStart(moduleInfo);

        _subject.Initialize();

        splashScreenService.ModuleLoadEnd(moduleInfo);
    }
}

Now, when you want to instantiate one of your ~15 classes, just run it through the decorator, like: 现在,当你想要实例化你的~15个类中的一个时,只需通过装饰器运行它,如:

IModule obj = new ModuleDecorator(new OneOfMy15Classes());

Of course, using an IoC container would make that better (eg StructureMap, Ninject, whatever you're using). 当然,使用IoC容器可以做得更好(例如StructureMap,Ninject,无论你使用什么)。

This use of the decorator pattern is pretty much what PostSharp and other AOP tools do behind the scenes anyway. 装饰模式的这种使用几乎就是PostSharp和其他AOP工具在幕后所做的事情。 If you really only need one decorator for one method on one interface, I think this is the way to go: no need to bring in an AOP tool just yet. 如果你真的只需要在一个接口上为一个方法提供一个装饰器,我认为这是要走的路:不需要引入AOP工具了。 But if you start creating decorators that essentially do the same thing but for different interfaces, that can get out of hand quickly, and that's when I'd bring in an AOP tool. 但是如果你开始创建基本上做同样事情但是针对不同界面的装饰器,那么这可能会很快失控,那就是我带入AOP工具的时候。

EDIT: I just noticed "ClassNameHere", you can get that via reflection with _subject.GetType().Name 编辑:我刚刚注意到“ClassNameHere”,你可以通过_subject.GetType().Name反射得到它_subject.GetType().Name

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM