限制注射我具有以下配置:通過命名空間
For<ITranslatorProvider>().Singleton().Use<TranslatorProviderA>();
我有3個翻譯提供商:TranslatorProviderA,B和C.
每一個應當在一定的命名空間來使用。
Project.Services>使用提供一個
Project.Site>用戶Provider B的
...
我可以注入提供A,B或C取決於從哪個命名空間中的要求來的?
這可能嗎?
限制注射我具有以下配置:通過命名空間
For<ITranslatorProvider>().Singleton().Use<TranslatorProviderA>();
我有3個翻譯提供商:TranslatorProviderA,B和C.
每一個應當在一定的命名空間來使用。
Project.Services>使用提供一個
Project.Site>用戶Provider B的
...
我可以注入提供A,B或C取決於從哪個命名空間中的要求來的?
這可能嗎?
您應該能夠使用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>();
})
);
我不認爲你可以注入基於命名空間的提供者。但是你可以通過使用命名實例實現同樣的事情(如果我沒有理解你的實現):
For<ITranslatorProvider>().Add<TranslatorProviderA>().Named("NS1");
For<ITranslatorProvider>().Add<TranslatorProviderB>().Named("NS2");
然後使用:
container.GetInstance<ITranslatorProvider>("NS1");