2013-03-25 127 views
1

限制注射我具有以下配置:通過命名空間

For<ITranslatorProvider>().Singleton().Use<TranslatorProviderA>(); 

我有3個翻譯提供商:TranslatorProviderA,B和C.

每一個應當在一定的命名空間來使用。

Project.Services>使用提供一個

Project.Site>用戶Provider B的

...

我可以注入提供A,B或C取決於從哪個命名空間中的要求來的?

這可能嗎?

回答

1

您應該能夠使用a convention做到這一點。像這樣的東西應該工作:

using System; 
using System.Linq; 
using StructureMap.Configuration.DSL; 
using StructureMap.Graph; 
using StructureMap.TypeRules; 

class TranslationConvention : IRegistrationConvention 
{ 
    public void Process(Type type, Registry registry) 
    { 
     if(!type.IsConcrete()) 
      return; 
     var ctor = Constructor.GetGreediestConstructor(type); 
     var translatorParameters= ctor.GetParameters() 
      .Where(p => typeof(ITranslatorProvider) 
      .IsAssignableFrom(p.ParameterType)); 
     if(!translatorParameters.Any()) 
      return; 
     Type translatorType = GetTranslatorType(type); 
     translationParameters.Aggregate(registry.For(type).Use(type), 
      (current, parameter) => 
       current.CtorDependency<ITranslatorProvider>(parameter.Name) 
       .IsConcreteType(translatorType)); 
    } 

    Type GetTranslatorType(Type type) 
    { 
     if(type.Namespace == "Project.Services") 
      return typeof(TranslatorProviderA); 
     if(type.Namespace == "Project.Site") 
      return typeof(TranslatorProviderB); 
     return typeof(TranslatorProviderC); 

    } 
} 

以上僅適用於登記的具體類型,因此,如果您希望該公約的類綁定到某個接口,你需要改變這一部分會議內容:registry.For(type).Use(type)到的東西更合適。查看StructureMap中的built in conventions以獲取一些想法。

可以使用常規的掃描:

ObjectFactory.Initialize(c => c.Scan(s =>  
    { 
     s.TheCallingAssembly(); 
     s.Convention<TranslationConvention>(); 
    }) 
); 
0

我不認爲你可以注入基於命名空間的提供者。但是你可以通過使用命名實例實現同樣的事情(如果我沒有理解你的實現):

For<ITranslatorProvider>().Add<TranslatorProviderA>().Named("NS1"); 
For<ITranslatorProvider>().Add<TranslatorProviderB>().Named("NS2"); 

然後使用:

container.GetInstance<ITranslatorProvider>("NS1");