Question

I have a Windows service where I use OWIN and NancyFX to host a website on top of it. On many places in my service, I use Unity to inject dependencies into classes, mostly services. However, if I use them in any Nancy modules, the dependencies get resolved twice because Nancy uses its own IoC container (TinyIoC).

Fortunately, Nancy allows to override the default IoC container generation and use of an existing one by creating a nancy bootstrapper. But how do I pass my existing IUnityContainer to the bootstrapper?

Basically, all I have to start OWIN is...

WebApp.Start<MyOwinStarter>(url);

How can I pass a Unity container to it to pass it further to the nancy bootstrapper?

Was it helpful?

Solution 2

Disclaimer: I really don't know if this is the best/cleanest/whatever solution to this problem. But for me it works.

I wrapped my container (Castle Windsor) like this, which is basically a singleton.

public class Container
{
    // static holder for instance, need to use lambda to construct since constructor private
    private static readonly Lazy<IWindsorContainer> instance = new Lazy<IWindsorContainer>(() =>
    {
        var container = new WindsorContainer();
        container.Install(FromAssembly.This());

        return container;
    });

    // private to prevent direct instantiation.
    private Container()
    {
    }

    // accessor for instance
    public static IWindsorContainer Instance
    {
        get
        {
            return instance.Value;
        }
    }
}

Then in my custom bootstrapper I access the already configured container like this

protected override Castle.Windsor.IWindsorContainer GetApplicationContainer()
{
  return Container.Instance;
}

OTHER TIPS

@ccellar got me into the right direction.

I created a static class UnityHelper with the following methods:

private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => {
    var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unityConfiguration");
    return new UnityContainer().LoadConfiguration(section);
});

public static IUnityContainer GetConfiguredContainer() {
    return container.Value;
}

Created a custom NancyBootstrapper class:

public NancyBootstrapper(IUnityContainer container) {
    if(container == null)
        throw new ArgumentNullException("container");
    this._unityContainer = container;
}


protected override IUnityContainer GetApplicationContainer() {
    return _unityContainer;
}

and passed the container to the bootstrapper in my web app startup class:

appBuilder.UseNancy(new NancyOptions {
    EnableClientCertificates    = true,
    Bootstrapper
        = new NancyBootstrapper(UnityHelper.GetConfiguredContainer())
});

Neat!

Actually, the easiest and correct way, would be to inherit a new bootstrapper class from the Bootstrapper type you are using - in your case WindsorNancyBootstrapper and override the GetApplicatioContainer method and return your instance

You can read more about it here https://github.com/NancyFx/Nancy.bootstrappers.windsor#customizing

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