NancyFx / Nancy.Bootstrappers.Windsor

Nancy boostrapper for the Windsor container
http://nancyfx.org
MIT License
14 stars 24 forks source link

Registration of Func<IRouteCache> not playing nice with Windsor facilities #9

Closed nikp closed 12 years ago

nikp commented 12 years ago

I'm having a strange issue trying to upgrade from Nancy 0.7 to 0.12 (Yes, it's a bit overdue). Previously I was registering a facility to do logging for all my services inside my bootstrapper:

    protected override void ConfigureApplicationContainer(IWindsorContainer existingContainer)
    {
        existingContainer.AddFacility<LoggingFacility>();
        existingContainer.Register(Component.For<LoggingInterceptor>());
        ...other registration
    }

LoggingFacility looks like this:

public class LoggingFacility : AbstractFacility 
{
    protected override void Init() { Kernel.ComponentRegistered += KernelComponentRegistered; }

    static void KernelComponentRegistered(string key, IHandler handler)
    {
        if (!ShouldProxyComponent(handler))
            return;

        // Don't add more than one logging interceptor to a component
        handler.ComponentModel.Interceptors.AddIfNotInCollection(InterceptorReference.ForType<LoggingInterceptor>());
    }

    static bool ShouldProxyComponent(IHandler handler)
    {
        //Don't log interceptors themselves
        if (typeof(IInterceptor).IsAssignableFrom(handler.ComponentModel.Implementation)) 
            return false;

        //Don't put proxy around any late-bound (usually factory-created) component
        if (handler.ComponentModel.Implementation == typeof(LateBoundComponent))
            return false;

        return true;
    }
}

Unfortunately since upgrading to 0.12/Castle 3.1, the following line in WindsorNancyBootstrapper.RegisterTypes is causing some problems

        container.Register(Component.For<Func<IRouteCache>>()
            .UsingFactoryMethod(ctx => (Func<IRouteCache>) (ctx.Resolve<IRouteCache>)));

Basically, Castle tries to create a dynamic proxy around Func. This would be fine if this registration triggered the event my facility subscribed to, to but it doesn't. And yet the interceptor seems to be registered anyway.

When trying to create a proxy it obviously fails because MulticastDelgate (IL's parent for Func<>) is sealed: TypeLoadException Could not load type 'Castle.Proxies.Func`1Proxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=a621a9e7e5c32e69' because the parent type is sealed.

I'm not sure what do here, does anyone have any experience with Facilities and Nancy 0.12?

nikp commented 12 years ago

Could this be related: https://github.com/NancyFx/Nancy.Bootstrappers.Windsor/pull/8 ?

nikp commented 12 years ago

Registering a TypedFactoryFacility in my bootstrapper seems to have given me the ability in my LoggingFacility to see if I need to proxy Func<> or not. Perhaps Nancy Windsor bootstrapper shoudl automatically register this facility?

thecodejunkie commented 12 years ago

@nikp I am a very poor Windsor user so I unfortunatly I don't have the knowledge to decide if this is a good or bad idea based on the information you have provided =/ Could you elaborate? =)

nikp commented 12 years ago

I believe the other pull request registers the TypedFactoryFacility in the bootstrapper solving this problem :) Unfortunately the reason for the resolution is a magical mystery to me, and I cannot elaborate further.

thecodejunkie commented 12 years ago

@nikp thanks you for the update. So this issue can be closed in favor of pulling in the open pull request?

nikp commented 12 years ago

I believe so :)

thecodejunkie commented 12 years ago

@nikp awesome! Thank you