【问题标题】:How to set a default constructor argument to null with StructureMap?如何使用 StructureMap 将默认构造函数参数设置为 null?
【发布时间】:2010-10-06 20:41:01
【问题描述】:

一个类有一个以 IMyInterface 作为参数的唯一构造函数。如果我定义 IMyInterface 的具体类型并将其注册到 StructureMap 则没有问题,我的类可以用这种具体类型实例化。

但是,在某些情况下,不会注册具体类型。在这种情况下,我想为 IMyInterface 参数接收 null。相反,我得到了一个例外:

结构图异常代码:202 没有为 PluginFamily IMyInterface 定义默认实例。

是否可以为缺少的插件定义默认值?

上下文:我的类是一个服务,使用 Spark 视图引擎并定义了一些默认命名空间。该服务使用 ISparkNamespacesProvider (IMyInterface) 添加其他命名空间。客户端应用程序可以注册或不注册这样的提供程序。这就是为什么服务的构造函数要么接收提供者,要么不接收提供者。

【问题讨论】:

    标签: dependency-injection constructor inversion-of-control structuremap


    【解决方案1】:

    取自here

    For<IService>().Use<MyService>()
     .Ctor<IMyInterface>("nameOfParameter").Is(null);
    

    但是你应该想想为什么你的类依赖于IMyInterface。如果它是可选的 - 那是代码的味道。也许您应该将其重构为需要它的方法的方法参数或可设置的属性。

    应该不需要在具体实现和 null 之间切换。在组合根处组合依赖关系图时,您应该确切知道没有.If(isSomething()).Use&lt;MyService&gt;().Ctor&lt;IMyInterface&gt;(null) 的依赖关系。

    您可能想查看this tekpub 演示和this book(查找所谓的 MEAP 访问)关于 DI 和 IOC。


    实现您想要的一种方法是使用所谓的“poor man dependency injection”。即——定义第二个构造函数:

    public MyClass():this(null){...}
    

    但我不建议这样做。

    【讨论】:

    • null 必须被强制转换为 IMyInterface 以避免模棱两可的调用。不幸的是,它不起作用。当我定义一个具体类型并将其注册到 SM 时,仍然传递 null。因此,您的代码似乎没有定义默认参数,而是为此参数定义了强制值。如果我删除您的代码,则使用具体类型。
    • @Nicolas 在配置中应该只指定一个具体的实现。否则 - 你的设计很可能是错误的。
    • @Nicolas 也许你可以在这里发布需要IMyInterface 的课程?使用IMyInterface的构造函数和部分。
    • @Nicolas 为什么会有具体实现未知的情况?
    • 我不会在 null 或具体类型之间动态切换。在初始化时,我要么定义具体类型,要么不定义(换句话说,客户端应用程序 A 将定义一个,客户端应用程序 B 将不定义)。
    【解决方案2】:

    StructureMap 现在通过 UseIfNone https://structuremap.github.io/registration/fallback-services/ 支持这种情况

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-03
      • 1970-01-01
      • 2017-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      相关资源
      最近更新 更多