Ninject, from Zero to Hero – Part 3

Depuis l’émergence du mouvement Craft, le Clean Code et les principes SOLID sont à la mode. Tout développeur qui se respecte doit produire du code maintenable, testable et réutilisable. Dans cet article, nous allons vous présenter Ninject, un outil dont le but est de faciliter la production d’un tel code.

Suite du deuxième article sur Ninject dans lequel nous avons vu comment gérer la durée de vie. Nous allons regarder cette fois-ci comment faire des injections conditionnées.

Injection conditionnée dans Ninject

Au moment du binding, on peut spécifier des conditions à Ninject pour déduire la classe à injecter par constructeur. On va, par exemple, conditionner l’insertion d’une data access factory. Grace à la méthode « WhenTargetHas », on conditionne l’injection.

var kernel = new StandardKernel();
 
kernel.Bind<IDataAccessFactory>()
    .To<DatabaseFactory>()
    . WhenTargetHas<DataBase1>()
    .WithConstructorArgument("database", "DataSource=DataBase1;User Id=user;Password=Password");
 
kernel.Bind<IDataAccessFactory>()
    .To<DatabaseFactory>()
    . WhenTargetHas<DataBase2>()
    .WithConstructorArgument("database", "DataSource=DataBase2;User Id=user2;Password=Password2");
 
kernel.Bind<MyClass>().ToSelf();

Dans l’exemple suivant, « MyClass » est de la forme :

public class MyClass
{
    private IDataAccessFactory dataAccessFactory;
 
    public MyClass([DataBase1]IDataAccessFactory dataAccessFactory)
    {
        this.dataAccessFactory = dataAccessFactory;
    }
}

Ainsi, dans l’exemple, on utilisera la chaîne de connexion « DataSource=Database1 ;User Id=user ; Password=Password ». Nous avons donc conditionné l’injection en fonction de l’attribut qui a été appliqué sur le paramètre d’entrée.
On peut aussi décider que l’injection sera conditionnée par le nom du paramètre de notre classe « MyClass », ce qui ressemblera à :

public class MyClass
{
    private IDataAccessFactory dataBase1;
 
    public MyClass(IDataAccessFactory dataBase1)
    {
        this.dataBase1 = dataBase1;
    }
}

Pour que cela marche à la place de la méthode « WhenTargetHas », on va utiliser la méthode « When ». Cette méthode permet de spécifier n’importe quelle condition au moment de l’injection.

var kernel = new StandardKernel();
 
kernel.Bind<IDataAccessFactory>()
    .To<DatabaseFactory>()
    .When(ctx => ctx.Target.Name == "database1")
    .WithConstructorArgument("database", "DataSource=DataBase1;User Id=user;Password=Password");
 
kernel.Bind<IDataAccessFactory>()
    .To<DatabaseFactory>()
    .When(ctx => ctx.Target.Name == "database2")
    .WithConstructorArgument("database", "DataSource=DataBase2;User Id=user2;Password=Password2");
 
kernel.Bind<MyClass>().ToSelf();

Dans l’exemple, on a conditionné sur le nom du paramètre.
Dans l’exemple précédent, on a conditionné l’injection de manière statique. A l’exécution, on ne pourra pas changer l’attribut DataBase1 ou changer le nom de la variable. On va maintenant injecter la database factory en fonction d’un paramètre dans l’application.
On va créer une classe DatabaseChooser qui va nous permettre de choisir la database à utiliser :

public class DatabaseChooser
{
    public bool IsDataBase1 { get; set; }
 
    public IDataAccessFactory CreateDataAccessFactory()
    {
        if (this.IsDataBase1)
        {
            return new DatabaseFactory("DataSource=DataBase1;User Id=user;Password=Password");
        }
        else
        {
            return new DatabaseFactory("DataSource=DataBase2;User Id=user2;Password=Password2");
        }
    }
}

La configuration Ninject ressemblera à :

var kernel = new StandardKernel();
 
kernel.Bind<DatabaseChooser>().ToSelf().InSingletonScope();
 
kernel.Bind<IDataAccessFactory>()
    .ToMethod(ctx => ctx.Kernel.Get<DatabaseChooser>().CreateDataAccessFactory());
 
kernel.Bind<MyClass>().ToSelf();

On créé le DatabaseChooser en singleton pour pouvoir réutiliser la même instance à tout moment. Ensuite, on utilise « ToMethod » pour récupérer l’instance de DatabaseChooser et on créé la data access factory.

La suite dans un prochain article…

Tags: ninject,

Pas de commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *