45 votes

Ne pouvez pas combiner Usine / DI

Il suffit de supposer que j'ai un peu de classe Foo, qui a deux dépendances: une ISerializer et un IFileAccessHandler.

Maintenant, cette classe possède également d'autres dépendances fonctionnelles les dépendances. Je ne veux pas que quelqu'un l'instanciation de cette classe dans un état non valide, donc j'aurais aussi besoin de passer d'un domaine d'objet dans le constructeur.

Mais comment puis-je avoir que gérée par le Cio quand je sais aussi ce domaine objet de passer en ce moment je suis en fait à la création de la classe Foo?

J'ai fait l'objet domaine d'une propriété que j'ai mis par une Usine. Afin que l'Usine rend un Service Localisateur d'appels pour obtenir un correctement instancié "Foo" de la classe avec ses dépendances, et de plus qu'elle se remplit avec le bon de domaine objet et le retourne.

Mais est-ce la meilleure façon de le faire? J'aurais préféré le domaine partie de l'objet de mon constructeur pour le rendre plus apparents que vous avez réellement besoin de travailler avec des "Foo".

Des idées? Suis-je manqué quelque chose? Merci à l'avance!

72voto

Mark Seemann Points 102767

La solution par défaut pour DI quand vous ne pouvez pas associer un type de béton au moment de l'enregistrement est d'utiliser un Résumé de l'Usine

Dans votre cas, je voudrais définir une IFooFactory interface:

public interface IFooFactory
{
    Foo Create(DomainClass dc);
}

Cela vous permettra de définir une mise en œuvre concrète qui sait au sujet de votre infrastructure de services.

public class FooFactory : IFooFactory
{
    private readonly ISerializer serializer;
    private readonly IFileAccessHandler fileHandler;

    public FooFactory(ISerializer serializer, IFileAccessHandler fileHandler)
    {
        if(serializer == null)
        {
            throw new ArgumentNullException("serializer");
        }
        if(fileHandler == null)
        {
            throw new ArgumentNullException("fileHandler");
        }

        this.serializer = serializer;
        this.fileHandler = fileHandler;
    }

    public Foo Create(DomainClass dc)
    {
        return new Foo(this.serializer, this.fileHandler, dc);
    }
}

De cette façon, vous pouvez protéger les invariants de votre classe Foo, en vous permettant de rester avec le Constructeur d'Injection.

Dans le conteneur d'injection de dépendances, vous pouvez enregistrer le IFooFactory et de mise en œuvre correspondantes. Partout où vous avez une DomainClass instance et ont besoin d'un Foo exemple, vous serait alors prendre une dépendance sur IFooFactory et l'utiliser.

0voto

Metro Points 764

Je suis aussi de la difficulté avec cette question. Marque de l'exemple a des contraintes que le FooFactory est la création d'un béton de classe Foo. Et si c'était de créer un IFoo où la mise en œuvre est déterminée au cours de configuration de démarrage? Cela implique pour chaque alternative de mise en œuvre de IFoo (FooA, FooB, etc) vous avez besoin d'une mise en œuvre concrète de la correspondante de l'usine (FooAFactory, FooBFactory, etc). Ce qui me frappe comme redondant.

Si l'usine est défini au même niveau que la mise en œuvre et l'initialisation du Conteneur, je ne vois pas la faiblesse de référencement du conteneur par l'usine. Il conserve encore des références du conteneur de fuite dans le reste de votre application.

Meilleures salutations,

De métro.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X