Reputation: 197
Is there a way to register with Ninject, using conventions, all classes that implement a certain interface, associated with each class' name?
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*); <--
Then later
Container.Instance.Get<IClientCodeValidator>(clientName.ToUpper())
Upvotes: 0
Views: 289
Reputation: 5427
The way you're going about this is an anti-pattern called Service Locator. The recommended approach would be to use Abstract Factory instead. In that pattern, you would have an additional interface that is responsible for resolving the correct concrete implementation. For your example:
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)
}
}
this way you can inject IClientCodeValidatorFactory
into your constructor and avoid using Container.Instance
altogether.
then you can use Ninject.Extensions.Conventions to automatically bind validators to the interface:
kernel.Bind( x => x
.FromThisAssembly()
.SelectAllClasses().InheritedFrom<IClientCodeValidator>()
.BindAllInterfaces()
.Configure(b => b.InSingletonScope()));
Upvotes: 0