简体   繁体   English

如何将IoC容器传递给NancyFX? (OWIN,Unity)

[英]How to pass IoC container to NancyFX? (OWIN, Unity)

I have a Windows service where I use OWIN and NancyFX to host a website on top of it. 我有一个Windows服务,我使用OWIN和NancyFX来托管一个网站。 On many places in my service, I use Unity to inject dependencies into classes, mostly services. 在我服务的许多地方,我使用Unity将依赖项注入类,主要是服务。 However, if I use them in any Nancy modules, the dependencies get resolved twice because Nancy uses its own IoC container (TinyIoC). 但是,如果我在任何Nancy模块中使用它们,依赖关系会被解析两次,因为Nancy使用自己的IoC容器(TinyIoC)。

Fortunately, Nancy allows to override the default IoC container generation and use of an existing one by creating a nancy bootstrapper. 幸运的是,Nancy允许通过创建nancy bootstrapper来覆盖默认的IoC容器生成和现有容器的使用。 But how do I pass my existing IUnityContainer to the bootstrapper? 但是如何将现有的IUnityContainer传递给引导程序?

Basically, all I have to start OWIN is... 基本上,我只需要启动OWIN就是......

WebApp.Start<MyOwinStarter>(url);

How can I pass a Unity container to it to pass it further to the nancy bootstrapper? 如何将Unity容器传递给它以将其进一步传递给nancy bootstrapper?

@ ccellar got me into the right direction. @ ccellar让我走向正确的方向。

I created a static class UnityHelper with the following methods: 我使用以下方法创建了一个静态类UnityHelper:

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: 创建了一个自定义的NancyBootstrapper类:

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: 并将容器传递给我的web app启动类中的bootstrapper:

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

Neat! 整齐!

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. 我把这个容器(Castle Windsor)包裹起来,这基本上是一个单身人士。

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;
}

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 实际上,最简单和正确的方法是从你正在使用的Bootstrapper类型继承一个新的bootstrapper类 - 在你的情况下WindsorNancyBootstrapper并覆盖GetApplicatioContainer方法并返回你的实例

You can read more about it here https://github.com/NancyFx/Nancy.bootstrappers.windsor#customizing 你可以在这里阅读更多相关信息https://github.com/NancyFx/Nancy.bootstrappers.windsor#customizing

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM