如何使用StructureMap配置文件设置命名实例?

时间:2009-08-17 14:18:11

标签: structuremap

我已经做了很多谷歌搜索并在这里搜索,但找不到类似的问题或答案。

在典型的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添加多个命名实例的方法,就像上面的常规配置一样。 ProfileExpression中唯一可用的其他方法是Type<>(),但我不确定它是否可以用于此目的。

修改:我尝试使用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

因此即使我将个人资料设置为“日产”,GetNamedInstance<>("New")也会从错误的个人资料中返回一个实例 - 它应该返回NewNissanCar而不是NewHondaCar

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

2 个答案:

答案 0 :(得分: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");

});

答案 1 :(得分: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

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