Geeks With Blogs
Blog Moved to http://podwysocki.codebetter.com/ Blog Moved to http://podwysocki.codebetter.com/
Update: Fixed some code issue and added a bit more discussion

With our DC ALT.NET group, we've discussed IoC quite often as part of the discussion.  Some are pretty new to the concepts of using Dependency Injection with these IoC containers.  Instead, you'd find people with overloaded constructors all over the place and mocking out the dependencies in the unit tests and so on.

Anyhow, I have two favorite IoC containers, being Jeremy Miller's StructureMap and Castle Windsor.  If you unfamiliar how to use Castle Windsor, there is a nice set of tutorials here.  I'd have to say StructureMap is the lightest weight of all of them and I like the fluent interfaces for configuration, but when I need other things as well, like AOP, I switch to Castle Windsor.  Which brings us to today's post.

Why AOP?

With object oriented programming, we try to break down things into small, distinct parts with as little overlap as possible through Separation of Concerns (SoC).  However, some of these concerns defy any sort of encapsulation by having cross-cutting concerns.  Some of these include logging, transactions, security among other things. 

So, what options do we have for AOP in the .NET world?  Well, we have three that are mainstream and supported at this point:
  • Castle Windsor
  • Spring.NET
  • PostSharp
Today I'm going to briefly talk about Windsor Interceptors.  It's a powerful concept for being able to intercept calls while using Castle Windsor and quite easy to use.  Let's go through a quick sample.

Castle Windsor has an interface that you must implement in order to write an interceptor called IInterceptor that looks like this:

public interface IInterceptor
{
    void Intercept(IInvocation invocation);
}

So, let's create one for a simple logging application:

public class MeddlingInterceptor : IInterceptor
{
     public void Intercept(IInvocation invocation)
     {
          Logger.Write("Entering method " + invocation.Method.Name + " with user " + Thread.CurrentPrincipal.Identity.Name);

         // Maybe do some user validation
         invocation.Proceed();
         // Do some stuff afterwards if need be as well
     }
}

And now let's configure it to use with our class we have already defined called EmployeeRepository.

public class EmployeeRepository : IEmployeeRepository
{
     public void Save(Employee employee)
     {
          // Calls database to save employee
     }
}

And inside our config file is this lovely mess:

<component id=”meddlinginterceptor”
service=”Podwysocki.Interceptors.MeddlingInterceptor,
    Podwysocki.Interceptors”
type=”Podwysocki.Interceptors.MeddlingInterceptor,
    Podwysocki.Interceptors” /> 
<component id=”employeerepository”
service=”Podwysocki.Interceptors.IEmployeeRepository,
    Podwysocki.Interceptorsr”
type=”Podwysocki.Interceptors.IEmployeeRepository,
    Podwysocki.Interceptors”>
  <interceptors>
    <interceptor>${meddlinginterceptor}</interceptor>
  </interceptors>
</component>  

As you can see, I didn't have to change anything in my EmployeeRepository class at all in order for this to work.  It works rather seemlessly.  With the IInvocation interface, I can get the method name, the target, arguments and so on.  But, I also have the ability to reset any of those arguments as well. 

Imagine I want to wrap transactions so that it doesn't appear in my code and just happens behind the scenes.  Well, I can do that too through a given interceptor as well.

public class TransactionInterceptor : IInterceptor
{
     public void Intercept(IInvocation invocation)
     {
          using(TransactionScope scope = new TransactionScope())
          {
                // Maybe do some user validation
                invocation.Proceed();
          }
     }
}

Now, do I recommend that?  Well, that's another story because O/RMs are probably a better way to go with handling that, but still this can be done.

AOP in Domain Driven Design???

In a previous post, I covered the assertion that proper Domain Driven Design cannot be accomplished without AOP.  The assertion is that the domain model needs to stay as clean as possible, so that all other cross cutting concerns such as logging, transactions, security and whatnot do not belong in your model.  Instead, AOP needs to be implemented.  This of course has been hot topic on the Domain Driven Design mailing list.

Randy Stafford had a great response on this thread and I thank him for it.  He seems to indicate that it's not really necessary for most things and I'd have to agree.  To read his responses, they are here and here.

Conclusion

A lot of the Domain Driven Design stuff has me rereading Eric Evans book again looking for nuggets I missed the first time around, so it's definitely time to get back reading.  I've got way too many books on my pile!

kick it on DotNetKicks.com Posted on Wednesday, January 23, 2008 7:40 PM C# , Domain Driven Design | Back to top


Comments on this post: Aspect Oriented Programming with .NET with Windsor

# re: Aspect Oriented Programming with .NET with Windsor
Requesting Gravatar...
Is there a way to specify whether to do this on exiting a method instead of entering?
Left by Joe on Jan 24, 2008 8:32 AM

# re: Aspect Oriented Programming with .NET with Windsor
Requesting Gravatar...
Yes, you have that option of specifying that it's going to happen at the end. See here for an example

public void Intercept(IInvocation invocation)
{
invocation.Proceed();
// Do something on method exit
}

Once the proceed has been invoked, then you have the option of doing anything you want to on method exit.
Left by Matthew Podwysocki on Jan 25, 2008 8:45 AM

# re: Aspect Oriented Programming with .NET with Windsor
Requesting Gravatar...
Excellent post, I agree that AOP isn't strictly needed for DDD but there are some interesting options out there.
Left by Colin Jack on Mar 21, 2008 9:41 AM

# re: Aspect Oriented Programming with .NET with Windsor
Requesting Gravatar...
Hi.

I was looking for a book which treats the Aspect Oriented Programming in .Net in a full coverage way. I need it for my fifth degree thesy.

Thank you in advice

Alessandro.

P.S:Please, use my e-mail...
Left by Alessandro on Apr 11, 2008 4:33 AM

Your comment:
 (will show your gravatar)


Copyright © Matthew Podwysocki | Powered by: GeeksWithBlogs.net