Castle Windsor: Auto-register types from one assembly that implement interfaces from another

20,164

Solution 1

With AllTypes you can easily do this:

From http://stw.castleproject.org/(S(nppam045y0sdncmbazr1ob55))/Windsor.Registering-components-by-conventions.ashx:

Registering components one-by-one can be very repetitive job. Also remembering to register each new type you add can quickly lead to frustration. Fortunately, you don't have to do it, at least always. By using AllTypes entry class you can perform group registration of types based on some specified characteristics you specify.

I think your registration would look like:

AllTypes.FromAssembly(typeof(EmployeeService).Assembly)
    .BasedOn<IEmployeeService>()
    .LifeStyle.Singleton

If you implement a base type, like IService on your interfaces, you can register them all at once using the following construct:

AllTypes.FromAssembly(typeof(EmployeeService).Assembly)
    .BasedOn<IService>()
    .WithService.FromInterface()
    .LifeStyle.Singleton

For more examples, see the article. This has a very good description on what the possibilities are.

Solution 2

I took Pieter's answer forward just a little bit (the key being, as he suggested, AllTypes) and have come up with this:

// Windsor 2.x
container.Register(
    AllTypes.FromAssemblyNamed("MyApp.ServicesImpl")
    .Where(type => type.IsPublic)
    .WithService.FirstInterface()
    );

This goes through all public classes in the MyApp.ServicesImpl.dll assembly and registers each in the container using the first interface it implements. Because I want all the classes in the services assembly, I need no marker interface.

The above works for an old version of Windsor. The current Castle Windsor documentation for registering components for the latest version suggests the following:

// Windsor latest
container.Register(
    AllTypes.FromAssemblyNamed("MyApp.ServicesImpl")
    .Where(type => type.IsPublic) // Filtering on public isn't really necessary (see comments) but you could put additional filtering here
    .WithService.DefaultInterface()
    );
Share:
20,164
Neil Barnwell
Author by

Neil Barnwell

I'm an Application Developer and Software Architect for a wide variety of software solutions including websites and desktop applications. Most recently focussed on a bespoke warehouse management system using C# 3.5 and SQL Server 2008. Since my move to .NET I've become active in the community, attending monthly usergroup meetings and various conferences. I've even made a foray into speaking at usergroups about topics I am passionate about. While I love experimenting with new tech and have a hobby project hosted on CodePlex, my current focus is less on specific new technologies and more on good principles and techniques. When not at work I'm a family man, biker, amateur photographer, guitarist and of course, software developer.

Updated on July 16, 2022

Comments

  • Neil Barnwell
    Neil Barnwell almost 2 years

    I use Castle Windsor as my IoC container. I have an application that has a structure similar to the following:

    • MyApp.Services.dll
      • IEmployeeService
      • IContractHoursService
      • ...
    • MyApp.ServicesImpl.dll
      • EmployeeService : MyApp.Services.IEmployeeService
      • ContractHoursService : MyApp.Services.IContractHoursService
      • ...

    I use the XML configuration at the moment, and every time I add a new IService/Service pair, I have to add a new component to the XML configuration file. I want to switch all this over to the fluent registration API but haven't worked out exactly the right recipe to do what I want yet.

    Can anyone help? The lifestyles will all be singleton.

    Many thanks in advance.