0

Dans les démos de spring4d, ServiceLocator.GetService<MyType>('Name') est utilisé pour résoudre les types. Mais pourquoi ne pas utiliser GlobalContainer.Resolve<MyType>('Name')? Je ne vois aucun avantage dans cette approche ...Bonne pratique pour la résolution dans Spring4D?

+0

[Certains] (http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/) considérez [service locator] (http://stackoverflow.com/questions/22795459/is-servicelocator- anti-pattern) un anti-pattern. Je considérerais des alternatives à ces deux. –

+0

Puisque les deux utilisent des variables globales, ils ne sont pas cool, oui. Mais avez-vous une suggestion pour une alternative? –

+2

Je pense que vous pouvez simplement vous assurer que vous utilisez uniquement le conteneur dans [CompositionRoot] (http://stackoverflow.com/questions/6277771/what-is-a-composition-root-in-the-context-of- dependency-injection) de votre application et sera soit identique, tant que le graphe d'objet est construit complètement dans la racine de la composition (et que le conteneur n'est pas référencé en dehors de cet emplacement) alors le localisateur de service est fonctionnellement le même comme injection de dépendance. –

Répondre

1

Il y a un cas d'utilisation, où j'utilise ServiceLocator: lors du codage pour faire l'unité testable projets de code hérité ...

Il y a un vieux projet, où dans plusieurs endroits, il y a des appels constructeurs d'un objet, pour lesquels j'écris des tests (méthodes nouvelles et modifiées, dans les classes, où l'injection n'est pas possible, par exemple quand un formulaire est créé et détruit).

Dans tests unitaires, spring4d est utile pour instancier la classe sous test:

je peux utiliser le GlobalContainer dans le DPR pour le projet de production et un TContainer-objet spécial (test uniquement) qui est construit dans Testfixture.Setup et détruit dans Testfixture.TearDown ... Je réinitialise aussi le Service-Locator global pour utiliser mon Test-Container (Raison: J'ai de mauvaises expériences à utiliser GlobalContainer dans Test, vous ne pouvez pas désenregistrer un type de GlobalContainer dans Testfixture.TearDown). Donc, maintenant, j'ai une grande méthode dans le dpr, où j'enregistre tous les types à GlobalContainer dans le projet de code de production. Dans la Setup-Method de ma classe test-fixture, j'inscris tous les types nécessaires pour le test à mon Testing-Container. Et dans les méthodes, que j'ai changées pour les rendre unit-testables, je construis les classes-sous-test avec ServiceLocator, où autrefois les constructor-calls étaient utilisés. Pour moi, c'est le seul moyen de tester un tel projet de code hérité ... Mais mon objectif stratégique est de remplacer la majeure partie de ce code (partie par partie, y compris les ServiceLocators réinitialisés).) un jour. Il n'est tout simplement pas possible de le remplacer maintenant (trop de coûts, trop de risques ...).

+0

oh ok, si fondamentalement votre seule raison d'utiliser le localisateur de service est la possibilité de changer le conteneur sous-jacent - des sons raisonnables –

+0

Pas la seule raison ... L'attribut [Inject] n'est tout simplement pas possible ... le cycle de vie de certains objets est juste à l'intérieur d'une méthode ... comment faire avec [Inject]? – Markus

+0

pas possible je dirais –