Question

I'm trying to use Castle Windsor to create my message handlers because just using ...

MessageHandlers.Add(typeof(MyHandler));

... doesn't allow me to use constructor injection of other services, for example a logger

So, I've create an installer which registers all my handlers (of which there is currently one!)

public class MessageHandlerInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
            AllTypes
                .FromThisAssembly()
                .Where(t => t.IsSubclassOf(typeof (DelegatingHandler)))
                .Configure(c => c.LifeStyle.Custom(InstallerContext.LifestyleManager))
            );
    }
}

This works fine, when I run it through the debugger I can see the extra component registration in the container.

But when I try to set up the message handler factory for WCF Web Api it doesn't appear to work. (I have breakpoints in the SendAsync method which never gets hit)

public class MyApiConfiguration : WebApiConfiguration
{
    public MyApiConfiguration(IWindsorContainer container)
    {
        EnableTestClient = true;
        IncludeExceptionDetail = true;

        CreateInstance = ((serviceType, context, request) => container.Resolve(serviceType));
        ErrorHandlers = (handlers, endpoint, description) => handlers.Add(container.Resolve<GlobalErrorHandler>());
        MessageHandlerFactory = () => container.ResolveAll<DelegatingHandler>();
    }
}

So, I'm obviously missing something. I just don't know what it is. Can anyone enlighten me?

EDIT (extra config code, as requested)

public void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    AddServiceRoutes(routes);
}

private static void AddServiceRoutes(RouteCollection routes)
{
    Container = WindsorContainerBootStrap.CreateContainerAndInstallComponents<PerThreadLifestyleManager>();
    var config = new EtailApiConfiguration(Container);
    routes.MapServiceRoute<CustomersApi>("customer", config);
    routes.MapServiceRoute<ConsumerApi>("consumer", config);
    routes.MapServiceRoute<PricePlansApi>("priceplans", config);
}

EDIT 2 (The Solution)

I had a constructor to my Handler like so ...

    public MyHandler(DelegatingHandler innerChannel, ILogger logger)
        : base(innerChannel)
    {
        _logger = logger;
    }

... that wasn't getting called despite the changing the init code to use a lambda ...

MessageHandlerFactory = () => container.ResolveAll<DelegatingHandler>();

... so I added another constructor which just takes an ILogger and all is well. I figured that my container didn't know what a Delegating Handler was and that the MessageHandlerFactory must be dealing with that somehow.

Was it helpful?

Solution

You need to use the lambda for ctor injection, that is why it is there. BTW, you are missing a ()

How are you registering your routes, are you passing in the configuration object?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top