繁体   English   中英

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

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

我有一个(也是唯一一个)我想要使用方面的方法。 它是IModule.Initialize (该方法在我的解决方案中大约有15个类中找到)

它看起来像这样:

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

我希望我的方面在方法体执行之前运行它:

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

这之后:

splashScreenService.ModuleLoadEnd(moduleInformation);

边注:
我看着这个,想,好吧,是时候试试PostSharp了。 我听说它是​​冠军的AOP工具。 所以我启动了NuGet包(希望获得免费版本)并安装它。

它装载了DemoWare(即额外的安装程序)。 我个人并不介意。 但我不希望我的团队必须处理安装程序,这样我才能解决我的小问题。

除了演示之外,具有UI的事实(我猜)会使我的构建服务器变得困难。 (我使用Package Restore。)

如果我在面向方面编程中“全力以赴”,这些都是我愿意处理的事情。
但我只需要一个......


有没有办法“滚动自己”而不是很头疼?

我不会这么快就注销PostSharp。 您可能希望将您的问题/问题发布到SharpCrafters论坛 你现在的问题很小,但是如果你遇到AOP有用的其他问题,即使数量很少,像PostSharp,Castle DynamicProxy等工具也是必需的。

至于“滚动你自己”,你可以做的是使用装饰模式。 我不确定moduleInformation变量的来源,我假设你实际上打算输入moduleInfo

然后,假设您的界面看起来像:

public interface IModule
{
    void Initialize();
}

你有~15个实现IModule的类。 您想要添加一些涉及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);
    }
}

现在,当你想要实例化你的~15个类中的一个时,只需通过装饰器运行它,如:

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

当然,使用IoC容器可以做得更好(例如StructureMap,Ninject,无论你使用什么)。

装饰模式的这种使用几乎就是PostSharp和其他AOP工具在幕后所做的事情。 如果你真的只需要在一个接口上为一个方法提供一个装饰器,我认为这是要走的路:不需要引入AOP工具了。 但是如果你开始创建基本上做同样事情但是针对不同界面的装饰器,那么这可能会很快失控,那就是我带入AOP工具的时候。

编辑:我刚刚注意到“ClassNameHere”,你可以通过_subject.GetType().Name反射得到它_subject.GetType().Name

暂无
暂无

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

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