2009-08-17 69 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 

通知的配置文件的名稱是如何實際上是實例密鑰的名稱的一部分。我沒有通過代碼,但這似乎正在發生。