结构图 - 注入命名实例的集合

Structure Map - Inject Collection of Named Instances

这个问题与我之前问过(并回答过)的一个问题非常相似:

在我的注册表中有以下内容:

For<IMyObject>().Add<MyObjectType1>().Named("Type1");
For<IMyObject>().Add<MyObjectType2>().Named("Type2");
For<IMyObject>().Add<MyObjectType3>().Named("Type3");

我想将所有实例注入构造函数,这样我就可以检索任何命名实例。示例代码(产生 StructureMap 异常):

public class Example
{
  private Dictionary<string, IMyObject> _workers;

  public Example(Dictionary<string, IMyObject> workers)
  {
    _workers = workers;
  }

  public void DoSomeStuff(string mode)
  {
     var worker = _workers[mode];
     worker.DoStuff();
  }
}

我采用这种方法的理由是允许外部配置指定应如何处理某事(在上面的示例中 'mode' 将对应于命名实例)。

实际异常情况如下:

StructureMap.StructureMapException occurred
  ErrorCode=202
  HResult=-2146232832
  Message=StructureMap Exception Code:  202
No Default Instance defined for PluginFamily

我知道我可以在方法 DoSomeStuff 中使用 StructureMap 容器来检索命名实例,但是,这是一种反模式。

所以澄清我的问题:

希望这很清楚,如果需要进一步解释,请回复。

谢谢,

格雷姆

与其注入字典,不如注入 Func<string, IMyObject> 更好。这避免了 StructureMap 必须创建所有 IMyObject 个实例及其所有依赖项,而实际上只需要使用其中一个实例:

public class Example
{
  private Func<string, IMyObject> _workers;
  public Example(Func<string, IMyObject> workers)
  {
    _workers = workers;
  }

  public void DoSomeStuff(string mode) => _workers(mode).DoStuff();
}

您可以按如下方式注册您的Example

For<Example>()
    .Use(() => new Example(mode => container.GetInstance<IMyObject>(instanceKey: mode)));