【问题标题】:How to pass IoC container to NancyFX? (OWIN, Unity)如何将 IoC 容器传递给 NancyFX? (欧文,团​​结)
【发布时间】:2014-03-16 02:56:40
【问题描述】:

我有一个 Windows 服务,我使用 OWIN 和 NancyFX 在其上托管一个网站。在我服务的许多地方,我使用 Unity 将依赖项注入到类中,主要是服务。但是,如果我在任何 Nancy 模块中使用它们,则依赖关系会被解析两次,因为 Nancy 使用自己的 IoC 容器 (TinyIoC)。

幸运的是,Nancy 允许通过创建一个 nancy 引导程序来覆盖默认的 IoC 容器生成和现有容器的使用。但是如何将现有的 IUnityContainer 传递给引导程序?

基本上,我要启动 OWIN 就是……

WebApp.Start<MyOwinStarter>(url);

如何将 Unity 容器传递给它以进一步将其传递给 nancy 引导程序?

【问题讨论】:

  • 注入 IoC 容器。啊,讽刺。

标签: c# dependency-injection unity-container nancy owin


【解决方案1】:

实际上,最简单和正确的方法是从您正在使用的引导程序类型继承一个新的引导程序类 - 在您的情况下为 WindsorNancyBootstrapper 并覆盖 GetApplicatioContainer 方法并返回您的实例

您可以在此处阅读有关它的更多信息 https://github.com/NancyFx/Nancy.bootstrappers.windsor#customizing

【讨论】:

  • 这正是我们在回答中所描述的 - 不是吗?
【解决方案2】:

@ccellar 让我进入了正确的方向。

我使用以下方法创建了一个静态类 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;
}

创建了一个自定义的 NancyBootstrapper 类:

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


protected override IUnityContainer GetApplicationContainer() {
    return _unityContainer;
}

并将容器传递给我的网络应用启动类中的引导程序:

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

整洁!

【讨论】:

  • 感谢分享。出于任何原因,我还不知道 NancyOptions :)
【解决方案3】:

免责声明:我真的不知道这是否是解决此问题的最佳/最干净/任何解决方案。但对我来说它有效。

我这样包裹我的容器(温莎城堡),它基本上是一个单例。

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

然后在我的自定义引导程序中,我像这样访问已经配置的容器

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

【讨论】:

  • 很好的解决方案!我在下面发布了最终答案。 =)
猜你喜欢
  • 2015-09-29
  • 2013-01-12
  • 2011-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多