3

我有一个(也是唯一一个)我想使用方面的方法。它是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 的事实(我猜)会使我的构建服务器变得困难。(我使用包还原。)

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


有没有办法“自己动手”而不会让人头疼?

4

1 回答 1

1

我不会这么快就注销 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

于 2012-08-11T14:27:09.867 回答