Ninject根据惯例注册名称

时间:2016-12-07 12:26:42

标签: ninject ninject-extensions

有没有办法向Ninject注册,使用约定,实现某个接口的所有类,与每个类的名称相关联?

index.html

之后

interface IClientCodeValidator
{
    string ValidateClientCode(params IXpressionNode[] customParameters);
    string ValidatorName { get; }
}

public class Client1CodeValidator: IClientCodeValidator
{
    public Client1CodeValidator()
    {
         this.ValidatorName = "Client1";
    }
}

public class Client2CodeValidator: IClientCodeValidator
{
    public Client2CodeValidator()
    {
         this.ValidatorName = "Client2";
    }
}

Bind<IClientCodeValidator>()
        .To.ItsClasses()
        .InSingletonScope()
    .Named(*c => c.ValidatorName*); <--

1 个答案:

答案 0 :(得分:0)

您正在采用的方式是一种称为服务定位器的反模式。建议的方法是使用抽象工厂。在该模式中,您将拥有一个额外的接口,负责解决正确的具体实现。以你的例子:

interface IClientCodeValidatorFactory
{
    IClientCodeValidator GetFor(string client);
}

public class ClientCodeValidatorFactory : IClientCodeValidatorFactory
{
    private readonly IKernel _kernel;

    public ClientCodeValidatorFactory(IKernel kernel)
    {
        _kernel = kernel;
    }

    public IClientCodeValidator GetFor(string client)
    {
        // load from your configuration how client names are associated to Validators
        return _kernel.Get<IClientCodeValidator>(validatorName)
    }
}
通过这种方式,您可以将IClientCodeValidatorFactory注入构造函数中,并完全避免使用Container.Instance

然后您可以使用Ninject.Extensions.Conventions自动将验证器绑定到接口:

kernel.Bind( x => x
    .FromThisAssembly()
    .SelectAllClasses().InheritedFrom<IClientCodeValidator>()
    .BindAllInterfaces()
    .Configure(b => b.InSingletonScope()));