2016-12-07 1 views
0

Existe-t-il un moyen d'enregistrer avec Ninject, en utilisant des conventions, toutes les classes qui implémentent une certaine interface, associée au nom de chaque classe?Ninject s'enregistrer par convention avec des noms

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

Puis, plus tard

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

Répondre

0

La façon dont vous allez à ce sujet est un anti-modèle appelé service de localisation. L'approche recommandée serait d'utiliser Abstract Factory à la place. Dans ce cas, vous disposez d'une interface supplémentaire chargée de résoudre l'implémentation concrète correcte. Pour votre exemple:

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) 
    } 
} 

cette façon, vous pouvez injecter IClientCodeValidatorFactory dans votre constructeur et évitez d'utiliser Container.Instance tout à fait.

vous pouvez utiliser Ninject.Extensions.Conventions pour lier automatiquement validateurs à l'interface:

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

Ok, comment puis-je brancher l'usine dans le second extrait? J'ai essayé d'utiliser '.Configure (c => c.InSingletonScope(). NamedLikeFactoryMethod ((IClientCodeValidatorFactory f) => f.GetFor()' mais alors je dois fournir un paramètre à la méthode GetFor() – bdaniel7

+0

vous connectez l'usine en tant que liaison simple: 'Bind (). ();', injectez-le dans le constructeur de la classe consommatrice, puis appelez 'GetFor' dans le code utilisateur. –