2009-11-19 18 views
1

Je suis tombé sur un dilemme dont je pense qu'il vaut la peine de discuter ici.Est-il correct d'utiliser IoC pour l'extensibilité de mes entités ou du modèle de domaine?

J'ai un ensemble d'objets de domaine (vous pouvez aussi les appeler des entités, si vous préférez), qui reçoivent des données d'une couche d'accès distincte distincte qui est résolue avec un IoC.

Je pensais à rendre mon système très extensible, et je me promène si il est juste de résoudre également ces entités par l'IoC. Permettez-moi de présenter un exemple stupide.

Disons que j'ai un site Web pour lequel je l'interface suivante:

public interface IArticleData 
{ 
    int ID { get; } 
    string Text { get; set; } 
} 

Le concept est que le DAL implémente ces interfaces, et aussi un IDataProvider<TData> générique inteface, après quoi le DAL devient facilement remplaçable. Et il y a la classe suivante, qui l'utilise:

public class Article 
{ 
    private IArticleData Data { get; set; } 

    public int ID 
    { 
     get { return Data.ID; } 
    } 

    public int Text 
    { 
     get { return Data.Text; } 
     set { Data.Text = value; } 
    } 

    private Article(IArticleData data) 
    { 
     Data = data; 
    } 

    public static FindByID(int id) 
    { 
     IDataProvider<IArticleData> provider = IoC.Resolve<IDataProvider<IArticleData>>(); 
     return new Article(provider.FindByID(id)); 
    } 
} 

Cela rend l'ensemble du système indépendant de la mise en œuvre de DAL réelle (ce qui serait dans l'exemple, IDataProvider<IArticleData>).

Ensuite, imaginez une situation dans laquelle cette fonctionnalité n'est pas vraiment suffisante, et j'aimerais l'étendre. Dans l'exemple ci-dessus, je n'ai pas d'options pour le faire, mais si je fais implémentent une interface:

public interface IArticle 
{ 
    int ID { get; } 
    string Text { get; set; } 
} 

public class Article : IArticle 
{ 
    ... 
} 

Et puis, je supprimer toutes les dépendances à la classe de l'article et commencer à le résoudre comme transitoire Composant IArticle avec un IoC.

Par exemple, dans le château: <component id="ArticleEntity" service="IArticle" type="Article" lifestyle="transient" />

Après cela, si je dois prolonger, ce serait cette simple:

public class MyArticle : Article 
{ 
    public string MyProperty { ..... } 
} 

Et tout ce que je dois faire est de changer la configuration à ce : <component id="ArticleEntity" service="IArticle" type="Article" lifestyle="transient" />

Ainsi, quiconque utiliserait le système en question serait capable de remplacer toutes les classes simplement en réécrivant une ligne dans la configuration. Toutes les autres entités fonctionneraient correctement aussi, car la nouvelle implémenterait la même fonctionnalité que l'ancienne. D'ailleurs, cela semble être une bonne solution pour la philosophie de la «séparation des préoccupations».

Ma question est, est-ce la bonne chose à faire? Après une réflexion sérieuse, je ne pouvais pas trouver de meilleure façon de le faire. J'ai également considéré MEF, mais il semble être orienté vers la création de plugins mais pas pour remplacer ou étendre des parties déjà complètes d'un système comme celui-ci.

J'ai lu beaucoup SO questions (et aussi d'autres sources) sur le sujet, les plus notables sont les suivants: How should I handle my Entity/Domain Objects using IoC/Dependency Injection? et IoC, Where do you put the container?

Et je suis aussi peur que je tombe aux problèmes décrits sur les pages suivantes: http://martinfowler.com/bliki/AnemicDomainModel.html et http://hendryluk.wordpress.com/2008/05/10/should-domain-entity-be-managed-by-ioc/

et une chose: cela augmenterait la testabilité de l'ensemble du système, non?

Qu'en pensez-vous?

EDIT: Une autre option serait de créer un modèle d'usine pour ces entités, mais IoC.Resolve<IArticle> est plus simple que IoC.Resolve<IArticleFactory>().CreateInstance()

Répondre

3

Je pense que vous pouvez être des choses trop compliquer. Auriez-vous jamais besoin de remplacer l'article avec un autre type qui a mis en place IArticle?

Les conteneurs IoC sont mieux utilisés lorsque vous avez un composant de niveau supérieur qui dépend d'un composant de niveau inférieur et que vous souhaitez que le composant de niveau supérieur dépende d'une abstraction de ce composant car le composant de niveau inférieur opérations internes qui rendent difficile de tester le composant de niveau supérieur, par exemple accès à la base de données Ou le composant de niveau inférieur peut représenter une stratégie particulière dans votre application qui peut être interchangeable avec d'autres stratégies, par ex. une passerelle de base de données qui résume les détails du travail avec les API de base de données spécifiques au fournisseur.

Comme l'article est une classe de style POCO simple, il est peu probable que vous ayez des avantages à en créer des instances dans un conteneur IoC.

+0

C'est fondamentalement vrai, mais s'il y a un cas où il a besoin de plus de logique métier, il serait utile s'il pouvait être remplacé. (Bien sûr, l'exemple dans la question est juste un stupide, pas une vraie classe.) – Venemo

+0

@Venemo: si c'est le cas, peut-être les éléments de l'article qui représentent la logique métier interchangeable devraient être définis en termes abstraits et injectés dans la classe Article par le conteneur IoC. – pmarflee

+0

Après réflexion, je suis vraiment d'accord avec vous, c'était vraiment trop compliqué. J'ai créé un modèle de dépôt simple, et cela semble résoudre le problème. – Venemo