2008-11-11 4 views
9

Je commence juste avec des conteneurs IoC donc excuses si c'est une question stupide.Est-ce qu'un conteneur IoC remplace l'utilisation des usines

J'ai code comme suit dans une application

internal static class StaticDataHandlerFactory 
    { 
     public static IStaticDataHandler CreateHandler(StaticDataUpdate staticDataUpdate) 
     { 
      if (staticDataUpdate.Item is StaticDataUpdateOffice) 
      { 
       return new OfficeUpdateHandler(); 
      } 

      if (staticDataUpdate.Item is StaticDataUpdateEmployee) 
      { 
       return new EmployeeUpdateHandler(); 
      } 

      if (staticDataUpdate.Item == null) 
      { 
       throw new NotImplementedException(
        string.Format("No static data provided")); 
      } 
      else 
      { 
       throw new NotImplementedException(
        string.Format("Unimplemented static data type of {0}", staticDataUpdate.Item.GetType().FullName)); 
      } 
     } 
    } 

Il est essentiellement une usine simple qui retourne la bonne stratégie pour le traitement des données d'entrée.

Un conteneur IoC me permettrait-il d'éliminer ce type de code? C'est-à-dire: cela me permettrait-il de choisir dynamiquement une implémentation concrète à charger en fonction du type d'un paramètre d'entrée?

Ou suis-je loin du cours ici?

Répondre

7

En fait, bien qu'il soit possible de remplacer une partie du code par un système d'inversion de contrôle, ce n'est pas évident pour moi que ce soit une bonne idée. L'injection de dépendance tend à être la meilleure pour la configuration des systèmes, pas la création dynamique d'objets. Pour le dire différemment, le conteneur lui-même est une variable globale énorme et en tant que telle devrait apparaître dans une grande partie de votre code. En outre, le code semble enfreindre le code Law of Demeter. Il semble que le paramètre doit être de type "StaticDataUpdateItem" plutôt que "StaticDataUpdate". Avec cela observé, il y a un argument assez fort pour réécrire ce code comme un appel de méthode sur le StaticDataUpdateItem.

J'ai beaucoup utilisé l'IoC, mais la création d'objets dynamiques est encore mieux gérée en utilisant un motif d'usine abstrait. En bref, si vous n'aimez pas l'idée d'ajouter une méthode à l'élément lui-même pour générer le handle, le code est probablement mieux laissé tel qu'il est.

0

La réponse courte est oui, elle le permet. Cette blog post montre une manière élégante de choisir l'implémentation à l'exécution en utilisant Windsor. L'auteur, Ayende, élabore here et here.

Je n'ai pas encore essayé, mais je m'attends à bientôt.

2

Vous n'êtes pas loin du tout; la façon dont je le comprends, vous êtes assez proche. La façon dont je structurerais le plus souvent ce genre de chose est de transformer votre classe Factory en votre conteneur IoC, simplement en permettant aux UpdateHandlers qui sont retournés d'être spécifiés en utilisant Dependency Injection. Ainsi, au lieu d'avoir la logique dans votre code qui spécifie que StaticDataUpdateOffice signifie renvoyer OfficeUpdateHandler, vous pouvez transformer votre code en disant simplement que StaticDataUpdateOffice retourne ce que contient une variable (nouvellement spécifiée) m_officeUpdateHandler; Tant que votre cadre s'assure que vous définissez la valeur de m_officeUpdateHandler avant d'appeler votre usine, vous êtes prêt à partir. Et vous pouvez changer la valeur du m_officeUpdateHandler pour tout ce que vous voulez au moment de l'exécution lorsque vos besoins changent.

Cette injection de dépendances vous permet de contrôler le processus d'inversion de contrôle; vous pouvez avoir une usine simple qui renvoie vos gestionnaires, et vous pouvez faire abstraction de la logique qui contrôle quel gestionnaire est renvoyé à un emplacement différent, le cas échéant. Note: mon expérience avec ce genre de choses est très fortement influencée par mon expérience (très positive) avec Spring, et cela peut colorer mon interprétation de votre question (et la réponse).

0

Je suis d'accord avec les autres réponses ici, que oui, vous pouvez le faire de cette façon. Mais pourquoi n'utilisez-vous pas un générique? Où les arguments peuvent être transmis en tant qu'arguments ctor (par exemple, Activator).

+1

Parce que les médicaments génériques sont résolues au moment de la compilation - il de prendre sa décision en fonction de ce type d'élément est en cours en tant que cargaison, une décision d'exécution. – Bevan

+1

Vous n'avez pas à résoudre les génériques lors de la compilation. Regardez Type.MakeGenericType() si vous ne me croyez pas. – dviljoen

-2

Je n'ai pas encore lu tous les mots qui ont beaucoup de sens.

IoC est plus pour config?

La création d'objets dynamiques est mieux quoi? Génériques? Tout cela est hors sujet.

1) L'IoC n'est rien d'autre qu'un gain de temps par rapport à l'implémentation de l'évangile 'composition over specialization/inheritance'. Donc, la règle n ° 1 pour l'utilisation d'un IoC est que vous devriez être vraiment fatigué de devoir faire face à de longs constructeurs qui suivent le 'bind to contract not implementation'. Dit d'une autre manière, c'est le motif stratey comme alternative au modèle de template pour les mêmes raisons (encapsuler ...) ... MAIS c'est plus de travail pour créer tous les types d'interface/abstract supplémentaires et il est plus de travail à faire à chaque fois avec tous les IServiceProvicerThis et IResolverThat ... Si vous n'êtes pas fatigué d'avoir à remplir fastidieusement contrats de code tels que:

IInterestingService intéressant = ... vous obtenez une instance cependant ..

ajouter environ trois autres lignes comme ceci ..

puis

IAmazementService service = nouveau AmazementService (intéressant, thesecondstrategy, le Tiers-, etc ...)

Cela vieillit. Donc IoC n'est jamais une question parce que n'importe qui assez intelligent pour coder en utilisant la conception solide saurait mieux. Ceux qui demandent ont toutes les mauvaises réponses. Donc, si vous rencontrez ce qui précède, alors absolument. Les conteneurs IoC sont sur le point de faire autant de travail de «création» que vous pouvez en tirer profit. Et l'abstraaction créationnelle la plus commune sur la nouvelle explicite est M. Factory.

Damon

Questions connexes