2009-08-17 107 views
2

我已经做了相当多的搜索和搜索,所以找不到类似的问题或答案。如何使用StructureMap配置文件设置命名实例?

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

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

没问题的。问题是我创建配置文件时无法做到这一点。解释如何使用配置文件中的大多数示例使用通过ProfileExpressionFor<>()方法:

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

我似乎无法找到一个方法来添加多个命名实例为同一PluginType,你可以用正则配置上面做的。通过ProfileExpression唯一可用的其他方法是Type<>(),但我不确定它是否可用于此目的。

编辑:我试图用Type<>()而不是For<>(),它似乎把我在正确的方向,但我碰到了另一个问题。为了更好地解释在这里是什么,我试图做一个更好的例子(这是我发布到structuremap用户群,没有答案了):

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(我猜它只是返回添加了对接口的最后一个具体类型)返回一个任意的具体类型。

回答

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"); 

}); 
+0

这将工作,如果我想重用一个现有的命名实例。不幸的是,我想注册一个新的具体类型并给它一个名字。看过我在问题中给出的例子后,我认为我应该不会再在配置文件中使用FooA。我会尽力解决它,以澄清我的意图。 – khaledh 2009-08-18 13:41:49

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 

通知的配置文件的名称是如何实际上是实例密钥的名称的一部分。我没有通过代码,但这似乎正在发生。

相关问题