2016-12-07 50 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'。 –