StructureMap在构造函数中传递null

edi*_*ode 5 c# structuremap dependency-injection

我在使用StructureMap构造函数中存在可为空参数的服务时遇到了一些困难.即

public JustGivingService(IRestClient restClient = null)
Run Code Online (Sandbox Code Playgroud)

在我的配置中,与所有其他服务一起,我通常能够以最小的方式逃脱,所以这里的问题可能只是缺乏理解.我这样做:

container.For<IJustGivingService>().Use<JustGivingService>()
Run Code Online (Sandbox Code Playgroud)

但是,由于可以为空的参数,我会发现我需要使用它来使其工作:

RestClient restClient = null;
container.For<IJustGivingService>().Use<JustGivingService>()
    .Ctor<IRestClient>("restClient").Is(restClient);
Run Code Online (Sandbox Code Playgroud)

然而,这对我来说确实有点脏,我觉得这可能是我想要实现的解决方案,而不是标准的方法.如果有更好的方法可以做到这一点,附带的信息将非常感谢.

Ste*_*ven 5

StructureMap不支持可选的构造函数参数,也不应该.如本博客文章所述:

可选的依赖关系意味着当未提供依赖项时,对依赖项的引用将为null.空引用使代码复杂化,因为它们需要针对null-case的特定逻辑.调用者可以插入没有行为的实现,即Null对象模式的实现,而不是传入空引用.这可以确保依赖项始终可用,类型可以要求这些依赖项,并且可怕的空值检查已经消失.这意味着我们维护和测试的代码更少.

所以解决方案是为StructureMap 创建一个Null Object实现IRestClient并注册该实现.

例:

// Null Object pattern
public sealed class EmptyRestClient : IRestClient {
    // Implement IRestClient methods to do nothing.
}

// Register in StructureMap
container.For<IRestClient>().Use(new EmptyRestClient());
Run Code Online (Sandbox Code Playgroud)

  • @jumpingcode,不,你不应该创建一个默认的构造函数.每个组件都应该有[只有一个构造函数](https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=97),它指定了所有类的依赖关系.所以你的`JustGivingService`组件应该有构造函数:`JustGivingService(IRestClient restClient)`(注意:没有`​​= null`)你也应该在StructureMap中注册你的空`IRestClient`实现. (2认同)