2016-12-07 64 views
0

有没有一种方法可以使用约定注册Ninject,实现某个接口的所有类都与每个类的名称相关联?Ninject注册按名称规定

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*); <-- 

再后来

Container.Instance.Get<IClientCodeValidator>(clientName.ToUpper()) 

回答

0

你要对这个办法就是所谓的服务定位器的反模式。推荐的方法是使用Abstract Factory代替。在这种模式下,你会有一个额外的接口负责解决正确的具体实现。对于你的例子:

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())); 
+0

好了,我怎么挂钩工厂第二片段?我尝试了使用 '.Configure(c => c.InSingletonScope()。NamedLikeFactoryMethod((IClientCodeValidatorFactory f)=> f.GetFor()' 但我必须提供一个参数给GetFor()方法 – bdaniel7

+0

你会将工厂作为一个简单的绑定连接:'绑定()。将();'注入到消费类的构造函数中,然后在用户代码中调用'GetFor'。 –