2

我已经在 SO 上进行了大量的谷歌搜索和搜索,但找不到类似的问题或答案。

在典型的 SM 配置中,您可以为单个 PluginType 添加多个命名实例:

ForRequestedType<IFoo>()
  .AddInstances( x => {
      x.OfConcreteType<FooA>().WithName( "FooA" );
      x.OfConcreteType<FooB>().WithName( "FooB" );
    } );

那里没问题。问题是我在创建个人资料时不能这样做。大多数解释如何使用配置文件的示例都使用For<>()传递的方法ProfileExpression

CreateProfile( "Default", p => {
    p.For<IFoo>().UseConcreteType<FooC>();
  } );

我似乎找不到为同一个 PluginType 添加多个命名实例的方法,就像您在上面使用常规配置所做的那样。唯一可用的其他方法ProfileExpressionType<>(),但我不确定它是否可以用于此目的。

编辑:我尝试使用Type<>()而不是For<>()它似乎将我带向正确的方向,但我遇到了另一个问题。为了更好地解释它,这是我正在尝试做的一个更好的例子(这是我发布到 structuremap-users 组的内容,还没有答案):

ObjectFactory.Initialize( x => {
    x.CreateProfile( "Nissan", p =>
    {
        p.Type<ICar>().Is.OfConcreteType<NewNissanCar>().WithName( "New" );
            p.Type<ICar>().Is.OfConcreteType<OldNissanCar>().WithName( "Old" );
    } );

    x.CreateProfile( "Honda", p =>
    {
        p.Type<ICar>().Is.OfConcreteType<NewHondaCar>().WithName( "New" );
        p.Type<ICar>().Is.OfConcreteType<OldHondaCar>().WithName( "Old" );
    } );

} );

ObjectFactory.Profile = "Nissan";

ICar newCar = ObjectFactory.GetNamedInstance<ICar>( "New" ); // -> returns NewHondaCar
ICar car = ObjectFactory.GetInstance<ICar>(); // -> returns OldNissanCar

因此,即使我将配置文件设置为“Nissan”,GetNamedInstance<>("New")从不正确的配置文件中返回了一个实例 - 它应该返回NewNissanCar而不是NewHondaCar.

有趣的是,GetInstance<>()使用了正确的配置文件,但是因为我无法传递实例名称,所以它从实现的配置文件返回任意具体类型ICar(我猜它只是返回为该接口添加的最后一个具体类型)。

4

2 回答 2

0

我对语法不是 100% 确定,但我相信这是正确的:

container = new Container(x => {

    x.ForRequestedType<IFoo>()
        .AddInstances(y =>
        {
            y.OfConcreteType<FooA>().WithName("FooA");
            y.OfConcreteType<FooB>().WithName("FooB");
        });

    x.CreateProfile("Default")
        .For<IFoo>().UseNamedInstance("FooA");

});
于 2009-08-18T01:04:32.167 回答
0

它看起来不像 StructureMap 在配置文件级别尊重命名实例。我刚刚使用 SM 2.6.3 尝试了汽车示例并得到了相同的结果。您还可以在以下输出中看到它ObjectFactory.WhatDoIHave()

ICar (ConsoleApplication1.ICar)                       
Scoped as:  Transient
      "New" Configured Instance of ConsoleApplication1.NewHondaCar, ConsoleApplication1
      "Old" Configured Instance of ConsoleApplication1.OldHondaCar, ConsoleApplication1

看起来配置文件也可以通过使用名称在内部实现,这可以解释为什么不支持它。当我为每个配置文件注册了一个未命名的实例时,我在输出中看到了这个:

ICar (ConsoleApplication1.ICar)                       
Scoped as:  Transient
      "Default Instance for Profile Nissan" Configured Instance of ConsoleApplication1.NewNissanCar, ConsoleApplication1
      "Default Instance for Profile Honda" Configured Instance of ConsoleApplication1.NewHondaCar, ConsoleApplication1

请注意配置文件的名称实际上是实例键名称的一部分。我没有浏览代码,但这似乎正在发生。

于 2012-07-17T15:56:33.260 回答