Je cherchais un moyen de nettoyer une instruction switch massive qui renvoyait une classe C# pour effectuer un travail (odeur de code ici).
Je ne voulais pas faire correspondre explicitement chaque interface à son implémentation concrète dans le module ninject (essentiellement une imitation du cas de switch long, mais dans un fichier diff), j'ai donc configuré le module pour lier toutes les interfaces automatiquement :
public class FactoryModule: NinjectModule
{
public override void Load()
{
Kernel.Bind(x => x.FromThisAssembly()
.IncludingNonPublicTypes()
.SelectAllClasses()
.InNamespaceOf<FactoryModule>()
.BindAllInterfaces()
.Configure(b => b.InSingletonScope()));
}
}
Créez ensuite la classe d'usine, en implémentant le StandardKernal qui récupérera les interfaces spécifiées et leurs implémentations via une instance singleton utilisant un IKernal :
public class CarFactoryKernel : StandardKernel, ICarFactoryKernel{
public static readonly ICarFactoryKernel _instance = new CarFactoryKernel();
public static ICarFactoryKernel Instance { get => _instance; }
private CarFactoryKernel()
{
var carFactoryModeule = new List<INinjectModule> { new FactoryModule() };
Load(carFactoryModeule);
}
public ICar GetCarFromFactory(string name)
{
var cars = this.GetAll<ICar>();
foreach (var car in cars)
{
if (car.CarModel == name)
{
return car;
}
}
return null;
}
}
public interface ICarFactoryKernel : IKernel
{
ICar GetCarFromFactory(string name);
}
Votre implémentation de StandardKernel peut alors accéder à n'importe quelle interface par l'identifiant de votre choix sur l'interface décorant votre classe.
Par exemple :
public interface ICar
{
string CarModel { get; }
string Drive { get; }
string Reverse { get; }
}
public class Lamborghini : ICar
{
private string _carmodel;
public string CarModel { get => _carmodel; }
public string Drive => "Drive the Lamborghini forward!";
public string Reverse => "Drive the Lamborghini backward!";
public Lamborghini()
{
_carmodel = "Lamborghini";
}
}
Utilisation :
[Test]
public void TestDependencyInjection()
{
var ferrari = CarFactoryKernel.Instance.GetCarFromFactory("Ferrari");
Assert.That(ferrari, Is.Not.Null);
Assert.That(ferrari, Is.Not.Null.And.InstanceOf(typeof(Ferrari)));
Assert.AreEqual("Drive the Ferrari forward!", ferrari.Drive);
Assert.AreEqual("Drive the Ferrari backward!", ferrari.Reverse);
var lambo = CarFactoryKernel.Instance.GetCarFromFactory("Lamborghini");
Assert.That(lambo, Is.Not.Null);
Assert.That(lambo, Is.Not.Null.And.InstanceOf(typeof(Lamborghini)));
Assert.AreEqual("Drive the Lamborghini forward!", lambo.Drive);
Assert.AreEqual("Drive the Lamborghini backward!", lambo.Reverse);
}