7
votes

Pourquoi l'unité utilise-t-elle un localisateur de services?

J'ai vu cette ligne de code dans plusieurs tutoriels d'utilisation de l'unité dans ASP.NET MVC3. J'étais sous l'impression que le localisateur de services est un anti-motif et non la meilleure pratique. Ce localisateur de service est-il autre chose autre que l'anti-motif défini, ou est cette ligne de code / cette mise en œuvre considérée comme une mauvaise pratique?

ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(Container));


6 commentaires

J'ai vu cela aussi, dans le Prism StockTrader Ri, ils utilisent également le servaclocator avec Mef. J'avais aussi l'impression que c'était un anti-motif, alors je suis surpris de le voir dans un RI. Je crois que c'est la même implémentation du modèle de localisateur de services que l'anti-motif défini.


Vous l'avez enregistré: en vous exemple, ce n'est pas une unité qui utilise le localisateur de services, mais plutôt de votre fiche de code dans l'unité à ASP.NET MVC3 via le localisateur de services. Les débats sur le modèle de localisateur de services sont de nature religieuse. L'équipe ASP.NET MVC a dû fournir un moyen d'utiliser votre conteneur DI préféré et c'est la façon dont ils l'ont mis en œuvre. Pensez aux alternatives. Voici quelques autres perspicacité à la question blog.ploeh.dk/2011/08/ 25 / ServicElocatorRolesvsMechanics.aspx


@zespri - Donc, toutes les implémentations d'unité n'utilisent pas un localisateur de services?


Il n'y a qu'une seule implémentation de l'unité connue pour moi. Il n'est pas Utiliser localisateur de services. C'est à vous de l'utiliser comme localisateur de service si vous êtes tellement enclin (même si l'unité ne l'appuyait pas explicitement), mais cela le soutient pour les cas comme celui-ci.


@zespri - J'aimerais beaucoup éviter d'utiliser le localisateur de services, connaissez-vous des didacticiels pour ASP.NET MVC3 qui montrent une simple configuration d'unité sans localisateur de services?


Regardez ici à l'excellent sous le hotte, regardez comment DI est câblé jusqu'à ASP.NET. Bradwilson.typepad.com/blog/2010/07/ ...


3 Réponses :


2
votes

C'est la même anti-patten que les gens parlent. Tout cette ligne est en train de définir le fournisseur de localisateur de service pour être une instance d'Unityservicelocator, c'est-à-dire d'utiliser la mise en œuvre de l'unité de l'ISERIVCELOCATOR. Éventuellement si vous souhaitez que votre propre implémentation soit votre propre implémentation, c'est iservicelocator et utilisez cela au lieu d'UNITYSERVICELOCATOR.

Utiliser le localisateur de services est considéré comme une mauvaise pratique pour diverses raisons telles que la liste indiquée ici



7
votes

Si vous créez un cadre conçu pour être conteneur agnostique, le localisateur de services (bien qu'il soit un point non go dans une application) est une couche d'indirection supplémentaire qui vous permet d'échanger l'unité de quelque chose de différent. En outre, l'utilisation du localisateur de services n'applique pas l'utilisation de DI pour les applications qui utilisent ce cadre.


0 commentaires

13
votes

Une question ancienne, mais au profit des autres:

tandis que je suis absolument d'accord avec le mantra "Le lieu de service est un anti-motif", il y a des exceptions définitivement à cette règle. P>

Quand vous Utilisez une injection de dépendance (comme unité), alors, oui, n'utilisez certainement pas ServicElocator et utilisez uniquement une injection de constructeur pour toutes vos classes de service. (N'utilisez également pas «Nouveau» pour autre chose que d'autres objets de valeur tels que DTO.) P>

Cependant, il existe des cas où vous ne pouvez tout simplement pas utiliser l'injection de constructeur, puis le seul moyen d'accéder à un accès à un Le service consiste à utiliser une solution de contournement pour accéder directement à votre conteneur d'unité, et dans de tels cas, le serveurélocator est un bon moyen standard d'accomplir cela. C'est le cas lorsque la classe n'est pas instanciée par vous (ou plus spécifiquement, elle n'est pas instanciée par l'unité) mais par la framework .NET par exemple. P>

Quelques exemples simples de l'endroit où le servicococator pourrait Soyez utile, est d'avoir accès aux services enregistrés dans votre conteneur d'unité de: P>

  1. Une implémentation d'un WCF iendpointBehavior ou iClientMessageInspector Li>
  2. Une implémentation d'un WPF IVALUECONVERTER LI>
  3. ou vous ne voudrez peut-être pas nécessairement avoir accès à des "services" de la classe, mais vous souhaitez simplement écrire le code de l'unité, mais pour une raison quelconque, la classe ne peut pas être instaré du tout (ou non Facilement) parce que cela serait normalement construit par le .NET Framework, vous extrayez votre code personnalisé en une classe testable et résolvez-la dans la classe non testable à l'aide du serveurLocator. LI> ol>

    Notez que cette ligne n'est pas idéale: p> xxx pré>

    La propriété ServiceLocator.current va exécuter le délégué fourni à chaque fois que vous accédez à l'heure actuelle, c'est-à-dire une New UnityservicElocator va être créé à chaque fois. Au lieu de cela, vous voulez probablement faire cela: P>

    IServiceLocator locator = new UnityServiceLocator(container);
    ServiceLocator.SetLocatorProvider(() => locator);
    


0 commentaires