Question

Quelque chose qui a été mise sur écoute depuis que je me lis une réponse à une autre question stackoverflow (celui précis me échappe maintenant) où un utilisateur dit quelque chose comme « Si vous appelez le Service Locator, vous le faites mal. "

Il était une personne avec une grande réputation (dans les centaines de milliers, je crois) donc je tends à penser que cette personne peut savoir ce dont ils parlent. Je me sers de DI pour mes projets depuis que j'ai commencé à apprendre à ce sujet et comment il se rapporte à des tests unitaires et que non. Il est quelque chose que je suis assez à l'aise avec maintenant et je pense Je sais ce que je fais.

Cependant, il y a beaucoup d'endroits où j'ai utilisé le service de localisation pour résoudre les dépendances dans mon projet. Une fois que le premier exemple vient de mes implémentations ModelBinder.

Exemple d'un liant à base de modèle typique.

public class FileModelBinder : IModelBinder {
    public object BindModel(ControllerContext controllerContext,
                            ModelBindingContext bindingContext) {
        ValueProviderResult value = bindingContext.ValueProvider.GetValue("id");

        IDataContext db = Services.Current.GetService<IDataContext>();
        return db.Files.SingleOrDefault(i => i.Id == id.AttemptedValue);
    }
}

pas une véritable mise en œuvre - juste un exemple rapide

Depuis la mise en œuvre de ModelBinder nécessite une nouvelle instance quand un classeur est premier demandé, il est impossible d'utiliser l'injection de dépendances sur le constructeur pour cette application particulière.

Il est ainsi dans beaucoup de mes cours. Un autre exemple est celui d'un processus d'expiration du cache qui exécute une méthode chaque fois qu'un objet cache expire dans mon site. Je lance un tas d'appels de base de données et que non. Là aussi j'utilise un localisateur de service pour obtenir la dépendance nécessaire.

Une autre question que j'avais récemment (que je posté une question ici à propos) était que tous mes contrôleurs exigeaient une instance de IDataContext que je DI pour - mais un méthode d'action nécessaire une autre instance de IDataContext. Heureusement Ninject est venu à la rescousse avec une dépendance nommée. Cependant, cela se sentait comme une bidouille et non une véritable solution.

Je pensais que je, au moins, compris le concept de séparation des préoccupations raisonnablement bien, mais il semble y avoir quelque chose de fondamentalement mauvais dans la façon dont je comprends l'injection de dépendance et le service de localisation de modèle - et je ne sais pas ce qui est <. / p>

La façon dont je comprends actuellement - et cela pourrait être mauvais aussi bien - est que, au moins dans MVC, le ControllerFactory cherche un constructeur pour un contrôleur et appelle le service de localisation de lui-même pour obtenir les dépendances nécessaires, puis les transmet . Cependant, je peux comprendre que toutes les classes et ce qui n'ont une usine pour les créer. Donc, il me semble que certains modèle de service de localisation est acceptable ... mais ...

  1. Quand est-il pas acceptable?
  2. Quel genre de modèle que je devrais être à l'affût quand je repenser la façon dont j'utilise le service de localisation de modèle?
  3. Ma mise en œuvre de ModelBinder mal? Si oui, que dois-je apprendre à réparer?
  4. Dans une autre question sur les lignes de celui-ci utilisateur Mark Seemann recommandé un résumé d'usine - Quel est le rapport ?

Je suppose que ce - je ne peux pas vraiment penser à toute autre question pour aider ma compréhension, mais toute information supplémentaire est grandement appréciée

.

Je comprends que DI pourrait ne pas être la réponse à tout et je vais peut-être par-dessus bord dans la façon dont je mets en œuvre, cependant, il semble fonctionner comme je l'attends à des tests unitaires et que non.

Je ne suis pas à la recherche de code pour corriger mon exemple d'implémentation - Je cherche à apprendre, à la recherche d'une explication pour corriger ma compréhension erronée

.

Je souhaite stackoverflow.com a la possibilité d'enregistrer des projets de questions. J'espère aussi celui qui répond à cette question obtient la quantité appropriée de réputation pour répondre à cette question car je crois que je demande beaucoup. Merci à l'avance.

Était-ce utile?

La solution

Considérez ce qui suit:

public class MyClass
{
  IMyInterface _myInterface;
  IMyOtherInterface _myOtherInterface;

  public MyClass(IMyInterface myInterface, IMyOtherInterface myOtherInterface)
  {
    // Foo

    _myInterface = myInterface;
    _myOtherInterface = myOtherInterface;
  }
}

Avec cette conception, je suis en mesure d'exprimer les exigences de dépendance pour mon type. Le type lui-même est pas responsable de savoir comment instancier une quelconque des dépendances, ils sont donnés à elle (injectée) quel que soit le mécanisme de résolution est utilisé [typiquement un conteneur IoC]. Attendu que:

public class MyClass
{
  IMyInterface _myInterface;
  IMyOtherInterface _myOtherInterface;

  public MyClass()
  {
    // Bar

    _myInterface = ServiceLocator.Resolve<IMyInterface>();
    _myOtherInterface = ServiceLocator.Resolve<IMyOtherInterface>();
  }
}

Notre classe est maintenant dépendante de la création des instances specfic, mais par délégation à un localisateur de services. En ce sens, Service Lieu peut être considéré comme un anti-modèle parce que vous n'êtes pas d'exposer les dépendances, mais vous permet des problèmes qui peuvent être attrapés par la compilation à bouillonner dans l'exécution. (Une bonne lecture est ). Vous cacher la complexité.

Le choix entre l'un ou l'autre dépend vraiment de ce que votre bâtiment sur le dessus et les services qu'elle fournit. En règle générale, si vous construisez une application à partir de zéro, je choisirais DI tout le temps. Il améliore la maintenabilité, favorise la modularité et rend les types de tests beaucoup plus facile. Mais, en prenant ASP.NET MVC3 comme un exemple, vous pouvez facilement mettre en œuvre SL comme cuit au four dans la conception.

Vous pouvez toujours opter pour une conception composite où vous pouvez utiliser IoC / DI avec SL, un peu comme en utilisant le services communs Locator . Vous composants pourrait être câblé par DI, mais par SL exposé. Vous pouvez même jeter la composition dans le mélange et utiliser quelque chose comme le Managed Extensibility Framework (qui se soutient DI, mais peut aussi être relié à d'autres conteneurs ou IoC localisateurs de service). Il est un grand choix de conception de faire, généralement ma recommandation serait de IoC / DI, si possible.

Votre conception spécifique Je ne dirais pas est faux. Dans ce cas, votre code n'est pas responsable de la création d'une instance du modèle liant lui-même, qui est au cadre de sorte que vous ne contrôlez pas que mais votre utilisation du localisateur de services pourrait probablement être facilement changé pour accéder à un conteneur IoC. Mais l'action d'appeler résolution sur le conteneur IoC ... envisageriez-vous pas que l'emplacement de service?

Avec un modèle de fabrique abstraite l'usine est spécialisée dans la création de types spécifiques. Vous ne vous inscrivez pas essentiellement enregistrer types pour la résolution d'une usine abstraite et qui construit tous les types que vous pourriez avoir besoin. Avec un service de localisation, il est conçu pour localiser les services et le retour de ces instances. Même d'un point de vue de la convention, mais très différent dans le comportement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top