按名称空间限制注入

时间:2013-03-25 12:22:26

标签: structuremap

我有以下配置:

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

我有3个翻译提供者:TranslatorProviderA,B和C.

每个应该在某些名称空间下使用。

Project.Services&gt;使用提供商A

Project.Site&gt;用户提供商B

...

我可以根据请求来自哪个命名空间注入提供者A,B或C吗?

这可能吗?

2 个答案:

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

答案 1 :(得分:0)

我认为你不能根据命名空间注入提供者。但是你可以通过使用命名实例来实现同样的目标(如果我理解你的实现):

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

然后使用:

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