NancyFx & Castle Windsor

I’ve just managed to fix a very odd problem with Castle Windsor and NancyFx. The error I was getting wasn’t much help at all really!

Can’t create component ‘Nancy.Routing.DefaultRouteCacheProvider’ as it has dependencies to be satisfied.
‘Nancy.Routing.DefaultRouteCacheProvider’ is waiting for the following dependencies:
– Service ‘System.Func`1[[Nancy.Routing.IRouteCache, Nancy, Version=0.22.2.0, Culture=neutral, PublicKeyToken=null]]’ which was not registered.

I’ve created a bootstrapper which among other this allows me to use a pre-existing container.

    public class NancyBootstrapper : WindsorNancyBootstrapper
    {
        private readonly IWindsorContainer _container;

        public NancyBootstrapper(IWindsorContainer container)
        {
            _container = container;
        }

        protected override IWindsorContainer GetApplicationContainer()
        {
            if (ApplicationContainer != null)
            {
                return ApplicationContainer;
            }

            _container.Kernel.Resolver.AddSubResolver(new CollectionResolver(_container.Kernel, true));
            _container.Register(Component.For<NancyRequestScopeInterceptor>());
            _container.Kernel.ProxyFactory.AddInterceptorSelector(new NancyRequestScopeInterceptorSelector());
            return _container;
        }

        protected override void RegisterBootstrapperTypes(IWindsorContainer applicationContainer)
        {
            // Note: Do NOT do the line below, this will cause the container to be registered twice and Windsor will throw an exception
            // applicationContainer.Register(Component.For<INancyModuleCatalog>().Instance(this));
        }
    }

Thanks to Ricardo Campos for getting me started! But whenever I tried starting nancy in self-host mode I immediately got the “missing IRouteCache” problem.

            var bootstrapper = _container.Resolve<INancyBootstrapper>();

            var uri = WebServerUri;
            _nancyHost = new NancyHost(uri, bootstrapper);

After much googling, head scratching, silent cursing and putting the world to rights a few times, I stumbled across a Stack Overflow answer. After reading through the link provided in the answer (https://github.com/NancyFx/Nancy.Bootstrappers.Windsor/pull/8). I tried adding the suggested fix.

        protected override void ConfigureApplicationContainer(IWindsorContainer existingContainer)
        {
            existingContainer.AddFacility<TypedFactoryFacility>();

            // some other cool stuff!
        }

Hey presto, it was all working and all is well with the world once more, until I hit the next bug that defies logic!

Advertisements

WCF Web Api MessageHandler Gotcha

If you find yourself getting this error message when you change your URL in the test client between you different APIs …

The HttpClient instance already started one or more requests. Properties can only be modified before sending the first request.

You have fallen foul of a little WCF Web Api gotcha. Message handlers need to be created each time they are required. I was using Castle Windsor to handle the lifetime of my message handlers

public class MessageHandlerInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        var path = Assembly.GetExecutingAssembly().GetDirectoryName();
        var filter = new AssemblyFilter(path, "ByBox*.dll");

        container.Register(
            AllTypes
                .FromAssemblyInDirectory(filter)
                .Where(t => t.IsSubclassOf(typeof (DelegatingHandler)))
                .Configure(c => c.LifeStyle.Custom(InstallerContext.LifestyleManager))
            );
    }
}

So, I’m using my InstallerContext’s lifestyle, but what I actually needed was this …

.Configure(c => c.LifeStyle.Transient)

I found this in a discussion on the wcf codeplex site

Using Castle Windsor with WCF Web Api (Preview 6)

I’ve got used to treating everything as a service in recent years, since I started using Castle Windsor. I only ever instantiate my own classes in unit/integration tests these days. My latest project has been to write a RESTful service using preview 6 of the WCF Web Api framework. (Also available via nuget, just add the WebApi.All package and you’re all set). It’s actually quite simple to make the web api use castle windsor.

From my Application_Start() method I call a ConfigureApi(RouteCollection routes) method. This create the config object and then sets up any routes …

private static void ConfigureApi(RouteCollection routes)
{
    Container = CreateContainer();

    var config = new MyApiConfiguration(Container);
    routes.SetDefaultHttpConfiguration(config);

    routes.MapServiceRoute<MyApi>("myresource");
}

I then set up CreateInstance, ErrorHandlers, and MessageHandlerFactory with anonymous methods which simply call the relevant Resolve methods on my container.

public class MyApiConfiguration : WebApiConfiguration
{
    public MyApiConfiguration(IWindsorContainer container)
    {
        EnableTestClient = GetSetting("TestClient");
        IncludeExceptionDetail = GetSetting("IncludeExceptionDetail");

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

        this.ValidateAllResourceTypes();
    }

    private static bool GetSetting(string settingName)
    {
        bool flag;
        bool.TryParse(ConfigurationManager.AppSettings[settingName] ?? "false", out flag);
        return flag;
    }
}

And that’s all there is to it. Simple really.

ValidateAllResourceTypes is something I will blog about another time. It uses reflection to register all resource types for validation via data annotations.