Wilfried Woivré & .Net

Unity : Gestion des paramètres primitifs

AVRI28

On a vu précédemment qu’avec de l’IoC comme Unity, il est facilement possible d’instancier des objets avec des paramètres complexes qui ont été au préalable enregistrés dans Unity. Cependant, il est aussi possible de résoudre des objets qui contiennent des types primitifs

Pour un cas concret, prenons ce code qui contient des paramètres optionnels.

public class MyClass : IMyInterface
{
    public MyClass(string param1, int param2, string param3 = "test", int param4 = 42)
    {
        Console.WriteLine("Params : {0}, {1}, {2}, {3}", param1, param2, param3, param4);
    }
}

Si l’on souhaite résoudre via Unity cette classe, il nous faut donc définir les paramètres, pour cela nous allons utiliser la classe ParametersOverride pour passer nos paramètres lors de la résolution de notre classe.

UnityRoot.Container.Resolve<IMyInterface>(new ParameterOverrides()
                                              {
                                                  {"param1", "val"},
                                                  {"param2", 3},
                                                  {"param3", "toto"},
                                                  {"param4", 12}
                                              });

 

Ainsi lors de la résolution de notre container, nous aurons bien la valeur de nos 4 paramètres.

image

 

Alors, comme vous avez pu le voir, dans mon exemple j’ai indiqué des paramètres optionnels, que j’ai néanmoins voulu résoudre lors de l’instanciation de ma classe. Parce qu’en effet à ce jour, Unity ne gère pas les paramètres optionnels, c’est à dire que si je souhaite résoudre ma classe de cette façon :

UnityRoot.Container.Resolve<IMyInterface>(new ParameterOverrides()
                                              {
                                                  {"param1", "val"},
                                                  {"param2", 3}
                                              });

Il se produira une erreur de type Microsoft.Practices.Unity.ResolutionFailedException car celui-ci n’arrive pas à résoudre les paramètres optionnels, comme on peut le voir ci-dessous

image

 

Donc mon conseil, soit vous passez par des propriétés que vous injectez, ce qui vous évite d’avoir des paramètres optionnels que vous devez absolument saisir. Soit vous pouvez définir tous vos paramètres de façon non optionnel.

Remonter

Unity : Enregistrer des types génériques et les résoudre

MARS15

Bon une fois n’est pas coutume, cela fait vraiment longtemps que je n’ai pas publié un billet n’ayant pas de rapport avec la plateforme Windows Azure. Même si j’avoue que je viens d’utiliser cette astuce dans la future version de mon blog sur Azure, mais vous en serez plus très bientôt j’espère !

 

Alors ma problématique est la suivante, je souhaitais faire un cache générique pour mon application, et bien entendu, j’utilise Unity dans tous mes projets, et donc celui ci ne fait pas exception à la règle. J’ai donc cherché à résoudre mes dépendances selon le type dont j’ai besoin.

 

On va donc commencer par créer une interface générique comme celle-ci  :

  1. public interface MyGenericInterface<T>
  2. {
  3.     void DisplayType(T instance);
  4. }

 

On va ensuite l’implémenter dans une classe :

  1. public class MyClass : MyGenericInterface<String>
  2. {
  3.     public void DisplayType(String instance)
  4.     {
  5.         Console.WriteLine(instance.GetType().FullName + Environment.NewLine);
  6.     }
  7. }

 

Voyons maintenant comment l’enregistrer dans un conteneur Unity :

  1. private static void Configure(IUnityContainer container)
  2. {
  3.     container.RegisterType(typeof (MyGenericInterface<>), typeof(MyClass));
  4. }

Comme on peut le voir, on enregistre les types de façon assez classique, il nous faut juste ajout les chevrons afin de définir un paramètre générique.

Si par hasard, vous avez plusieurs paramètres, par exemple, il faudra faire comme ci-dessous afin de définir qu’il y a bien 3 paramètres génériques

  1. private static void Configure(IUnityContainer container)
  2. {
  3.     container.RegisterType(typeof (MyGenericInterface<,,>), typeof(MyClass));
  4. }

 

Et maintenant, voyons comment résoudre nos types, si on prend l’exemple suivant :

  1. UnityRoot.EnsureInitialized();
  2. UnityRoot.Container.Resolve<MyGenericInterface<String>>().DisplayType("Hello");
  3.  
  4. try
  5. {
  6.     UnityRoot.Container.Resolve<MyGenericInterface<Int32>>().DisplayType(42);
  7. }
  8. catch (Exception ex)
  9. {
  10.     Console.ForegroundColor = ConsoleColor.Red;
  11.     Console.WriteLine(ex);
  12.     Console.ForegroundColor = ConsoleColor.White;
  13. }

 

On va donc essayer de résoudre une classe implémentant notre interface avec le type String, et ensuite avec le type Int32. Dans notre cas, nous n’avons ajouté qu’une classe avec une interface avec le type String.

Si nous lançons notre application, nous allons donc avoir ceci  :

image

 

Nous avons bien la résolution de notre premier élément, par contre la deuxième ne marche pas comme prévu, puisque nous n’avons pas enregistrer de classe avec notre interface implémentant le type Int32.

Voilà, je ne vous donne pas le code source de la solution, puisque tout est là, il ne manque que les références à Unity, et pour cela NuGet est votre meilleur ami !

Remonter

Live Meeting : MVVM Deep Dive / Tips & Tricks

JANV4

Merci à ceux qui était présent avant toute chose !

Avec Thomas Lebrun, nous avons présenté un Live Meeting sur quelques astuces que l’on peut utiliser avec le Design Pattern MVVM.

 

Vous pouvez retrouver les différentes démonstrations ici

Pour la rediffusion du Live Meeting que nous avons encore oublié d’enregistrer ….. Je publierais 4 vidéos prochainement avec 1 démonstration par vidéo.

DataTemplate : Appel de méthode du ViewModel depuis un DataTemplate situé dans un ItemsControl

DesignTime : Comment afficher des données en DesignTime avec une architecture de type MVVM

Unity : Comment utiliser Unity pour résoudre et instancier ces différents ViewModels

INotifyPropertyChanged : Différentes méthodes pour implémenter cette interface

Remonter

ASP.Net & Unity : Gestion des contrôleurs

JANV3

Dans un article précédent, je vous ai montré comment injecter vos différentes dépendances via Unity en utilisant plusieurs techniques. Si depuis, vous avez voulu essayer en ASP.Net MVC, vous vous êtes surement aperçu que l'on ne peut pas directement résoudre nos dépendances puisque la création des différents contrôleurs est par défaut géré par le Framework.

Donc avant de voir comment modifier cela, il faut comprendre comment une page est construite. (Image issue de : http://msdn.microsoft.com/en-us/magazine/dd695917.aspx)

image

 

On peut donc voir que lors du Worflow de création d’une page ASP.Net MVC, le MvcHandler interagit avec le IControllerFactory qui va lui fournir le, ou les, instances de IController qui correspondent, soient nos contrôleurs que nous utilisons en ASP.Net MVC. Et bien entendu, vous pouvez redéfinir vous même votre propre fabrique afin de pouvoir y placer la création de vos contrôleurs via Unity.

 

Déjà commençons par créer notre classe qui enregistre notre Container Unity :

public class UnityRoot
{
    private readonly static IUnityContainer _container = new UnityContainer();

    internal  static void EnsureInitialized()
    {
        
    }

    static UnityRoot()
    {
        Configure(_container);
        var controllerFactory = new UnityControllerFactory(_container);
        ControllerBuilder.Current.SetControllerFactory(controllerFactory);
    }

    private static void Configure(IUnityContainer container)
    {
        container.RegisterType<Interface1, ClassImpl1>();
        container.RegisterType<Interface2, ClassImpl2>();
    }
}

 

Ensuite, comme on peut le voir aux lignes 13 et 14, je créé une instance de IUnityControllerFactory qui va gérer la création des différents contrôleurs.

public class UnityControllerFactory : DefaultControllerFactory
{
    private IUnityContainer container;

    public UnityControllerFactory(IUnityContainer container)
    {
        this.container = container;
    }

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        IController controller;
        if (controllerType == null)
            throw new HttpException(404, String.Format("The controller for path '{0}' could not be found" +
                "or it does not implement IController.", requestContext.HttpContext.Request.Path));

        if (!typeof(IController).IsAssignableFrom(controllerType))
            throw new ArgumentException(string.Format("Type requested is not a controller: {0}", controllerType.Name), "controllerType");
        try
        {
            controller = container.Resolve(controllerType) as IController;
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException(String.Format("Error resolving controller {0}", controllerType.Name), ex);
        }
        return controller;
    }
}

Et voilà, uniquement en surchargeant la méthode GetControllerInstance, vous pouvez modifier la création de vos contrôleurs, ici en ajoutant les différentes implémentations de Interface1 et Interface2.

 

Voici les sources de l’application avec laquelle j’ai fait cet article.

 

Et merci à Julien Corioland de m’avoir donné cette astuce.

Remonter

Live Meeting : MVVM de A a Z

DÉCE7

Avec Thomas Lebrun, nous avons réalisé un Live Meeting autour du pattern MVVM, celui ci avait pour but de refaire un tour d’horizon de ce dernier.

Donc comme promis voici les sources et le powerpoint de la session.

N’oubliez pas que nous organisons d’autres live meeting à peu près tout les deux mois le mardi soir de 19h à 20h, vous pouvez retrouver la liste ici

 

La ressource MVVM In the Box dont on a parlait pendant les questions/réponses se trouve ici.

EDIT Il ne sera pas possible de rejouer le WebCasts, cependant, je vais vous représenter la technologie, ainsi que la démonstration de façon plus complète prochainement.

 

Vous pouvez télécharger la vidéo sur mon Skydrive, vu la taille, elle est contenu dans un fichier 7zip splitté en deux : ici et

Dîtes moi en commentaire, si vous savez où je pourrais Upload la vidéo en 1 seul morceau (Youtube à échoué vu la taille de la vidéo). Et d’ailleurs si vous voulez d’autres vidéos, sur d’autres sujets proposez aussi via le formulaire de contact, je verrais si je peux les faire.

Remonter