R – Castle Windsor: auto-register types that have dependency in constructor

castle-windsor

Most of the examples I see for Castle Windsor auto-register type that derive from some IFoo. However, I often have simple components (services) that just required IFoo in the constructor:

public class Service
{
  public Service(Service2 service, IFoo foo) {}
}
public class Service2
{
  public Service2(IFoo foo) {}
}

How do I make Windsor automatically register/recognize them? I see two ways:

  1. Browse all types in assembly, get their constructors, check if any of the constructor's parameter is registered in Windsor… and register it. The problem is that Service can depend on Service2 -> IFoo… I want CONTAINER to do this, not me.
  2. Somehow extend Windsor (facility, etc – I'm not expert here) so that the above happens during "Resolve" call – so that I don't need to browse all the meaningless types in all assemblies.

In both cases, however, I'll need a way to ask Windsor "Is type T your dependency – directly or indirectly via nested constructor?".

I really hate duplication, so I don't see why I need to manually register something that Windsor does already know about.

UPDATE: here's the code that seems to work. I'm really not expert in Windsor so I'm not sure if the code is OK.

     var dependencies = container.Kernel.GetAssignableHandlers(typeof(object));
     foreach (var type in typeof(ViewModel<>).Assembly.GetTypes().Where(x => x.Name.EndsWith("ViewModel")))
     {
        var ctorArgs = type.GetConstructors().SelectMany(x => x.GetParameters());
        var canBeResolved = dependencies.Any(dep => ctorArgs.Any(a => 
                     a.ParameterType.IsAssignableFrom(dep.ComponentModel.Service)));
        if (canBeResolved)
           container.AddComponent("viewModel" + type.Name, type);
     }

However, I would better have Windsor (or my extension) do this during resolve-time, because brosing ALL types is a bit overkill in my opinion, even though I narrow it with name filter.

Best Answer

If you're for option 2, there is a new extension point in works that does just that. It's not in the trunk yet (you can download the patch from discussion group, integrate it with the trunk and rebuild it yourself). It will be in Windsor v2.1 though.

For now you can do either that, do the up-front registration like you showed or develop some kind of convention, like put all the types in common namespace.

Related Topic