Archive for category Castle Windsor

Support for Arrays in Constructors using Castle Windsor

As I mentioned in my post Aspect Oriented Timing in C# with Castle Windsor, we are using Castle Windsor as our Inversion of Container on our current project.

In the process of adding a couple of new features, there were places where the new code had to fit in to existing places where there were a longer (more than simply just a single if/else) set of conditionals. To address the changes that I needed to make, I added another conditional to go with the existing ones. This change was in the mood of make it work, knowing I would come back after it worked to make it right, and that this change would allow me to confirm the smell I was “sure” I was smelling.

One I had it working, I came back to make it right. The route I wanted to go was to emulate the refactoring Replace Conditional with Polymorphism by creating a “handler” abstraction, and pulling the logic for each of the conditionals into a separate implementation of the handler.

My new interface was defined as:

public interface INewHandler
{
  bool CanHandle(ISomeObject obj);
  void Handle(ISomeObject obj);
}

I then moved out the logic in each of the conditionals, as well as the conditionals themselves into new handlers. The conditionals were moved into the CanHandle method, and the body of the conditional was moved to the HandleMethod of the implementation.

With these defined, it became just a matter of using a LINQ query to find either the first, or all items that could handle the object, and then just call the Handle method on the ones that matched the filter.

injectedHandlers.
    Where(h => h.CanHandle(someObj)).
    ForEach(h => h.Handle(someObj));

After having this, all we need now is the ability to have all of the implementations injected into the constructor. This gets us to the title of this post, about having arrays injected into constructors. First we have to configure the container to add a new ArrayResolver as a subresolver.

container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel));

After this, I want to pick up all implementations of the INewHandler in all assemblies.

container.Register(
    AllTypes.FromAssemblyInDirectory(new AssemblyFilter("bin")).
    BasedOn>INewHandler>().
    WithService.Base().
    Configure(c => c.LifeStyle.PerWebRequest)
);

After adding these two to the registration of Castle Windsor, I now get all implementations injected into my constructor when I declare a constructor parameter that is a type of INewHandler[].

Hope someone else can find this helpful.

–Proctor

Advertisements

, , , ,

Leave a comment

Aspect Oriented Timing in C# with Castle Windsor

I was making some refurbishments on some reporting code in our application that used EF and was suffering from the Select N+1 problem. If truth, it was much worse, as it was an Select N+1 problem up to 6 levels deep depending on where the report was run from.

I was changing the code to use a denormalized view from the database, and then run a SQL Query using Entity Framework. When doing this I was asked to get the timings of the report, both against the new way, and the existing way.

As this is incidental to what I was really trying to do, I did not want to litter timing code, and logging mechanisms into classes that already existed. This smelled of Aspect Oriented Programming (AOP). While I had not done anything using AOP before, I knew that it was great for cross-cutting concerns like logging, timings, etc. Having been digging into Clojure and LISP recently, this also seemed like cases of the :before, :after and :around methods in Common LISP, or the similar behavior in Eiffel as pointed out in Bertrand Meyer’s Object Oriented Software Construction, not to mention the time function in Clojure which is a function whose single concern is simply the to manage capturing the timing a function passed into it. My hope was to simplify, or un-complect, the code, and keep those concerns separate.

In our project, we have Castle Windsor setup as the IOC container, and Windsor supports a type of Aspect Oriented Programming using something called Interceptors. I found documentation on setting it up on a post by Ayende, and one Andre Loker. The issue was some of the places I wanted to setup the capturing of the timings were in different areas than where the handlers were registered for Windsor.

After some hunting around, I managed to come up with being able to add an interceptor to an already registered component by using the following line of code, where the IReportingService is the class I want to time the method calls around, and the LogTimingInterceptor is the class that captures the timing of the method call and sends it to the logger:

container.Kernel.GetHandler(typeof(IReportingService)).ComponentModel.Interceptors.Add(new InterceptorReference(typeof(LogTimingInterceptor)));

Hope someone else can find this useful,
–Proctor

, , , , , ,

2 Comments