Vaccano
Vaccano

Reputation: 82351

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. (The method is found in about 15 classes in my solution)

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. I have heard it is the AOP tool of champions. So I fired up the NuGet package (expecting to get the free version) and installed it.

And it is loaded with DemoWare (ie extra installers). 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. (I use 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?

Upvotes: 3

Views: 418

Answers (1)

Matthew Groves
Matthew Groves

Reputation: 26151

I wouldn't be so quick to write off PostSharp. You may want to post your questions/issues to the SharpCrafters forum. 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.

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.

Then, assuming your interface looks something like:

public interface IModule
{
    void Initialize();
}

And you have ~15 classes that implement IModule. You want to add some functionality involving ModuleInformation, so create a decorator class.

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:

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

Of course, using an IoC container would make that better (e.g. StructureMap, Ninject, whatever you're using).

This use of the decorator pattern is pretty much what PostSharp and other AOP tools do behind the scenes anyway. 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. 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.

EDIT: I just noticed "ClassNameHere", you can get that via reflection with _subject.GetType().Name

Upvotes: 1

Related Questions