1

J'ai implémenté un modèle de référentiel avec une ignorance de persistance. L'implémentation du référentiel n'interagit qu'avec mes objets d'entité, IUnitOfWork et ITable<T>. L'intention est que le IUnitOfWork ne soit pas réutilisé mais représente une seule transaction. Jusqu'à présent, j'ai implémenté en-mémoire ainsi que Linq-to-Sql des versions IUnitOfWork et ITable<T>.Quel motif de conception pour localiser mon IUnitOfWork?

Mon problème est que, en raison de l'injection IUnitOfWork dans le référentiel, je finis avec besoin de savoir comment instancier une nouvelle IUnitOfWork où que le dépôt est utilisé. Puisque c'est la pièce principale qui est supposée être connectable, j'ai l'impression d'avoir fait quelque chose de mal. Le modèle d'utilisation général est quelque chose comme ceci:

FooUnitOfWork unitOfWork = new FooUnitOfWork(); 
Repository repos = new Repository(unitOfWork); 
// ...act upon repos 
unitOfWork.Save(); 

Maintenant, il semble que j'ai besoin d'un autre modèle pour permettre à chaque utilisation du référentiel dans l'application pour obtenir l'unité correcte du travail (par exemple en mémoire, L2S, etc.).

Quel est le modèle le plus approprié pour cela? J'ai regardé Fowler's discussion on the topic mais aucun de ses exemples ne semble être un ajustement propre. Je me sens déjà comme la quantité d'abstraction que j'ai est plus que ce que je voudrais pour construire encore une autre indirection semble excessive. À l'heure actuelle, je me tourne vers un fournisseur d'application qui peut être configuré pour produire le bon IUnitOfWork. Suis-je hors-base ou est-ce ce qui est nécessaire pour être vraiment agnostique de mise en œuvre?

+0

Eh bien, vous avez besoin d'un contexte pour associer l'unité de travail (comme un thread ou httpcontext), vous devez ensuite utiliser une méthode usine pour obtenir l'unité de travail (vs new()). – meandmycode

+0

Une méthode d'usine statique (soutenue par un contexte de thread) serait une interface propre pour l'instanciation. Que diriez-vous de configurer la configuration (contexte DB, etc) que je configure actuellement dans les constructeurs 'UnitOfWork'? – mckamey

+0

Je voudrais gérer cela dans certains endroits autoritaire, si cela était une application web par exemple ..vous manipulez BeginRequest et créez une unité de travail (en transmettant toutes vos dépendances et config), puis enregistrez-le quelque part (le plus simple serait soit des membres d'instance dans le global, soit dans la collection Items), vous auriez alors une usine méthode (ou quelque chose de similaire) qui sait où chercher l'instance de l'unité de travail ... vous pouvez travailler pour faire quelque chose de beaucoup plus sophistiqué mais tout ce que vous faites est de mettre en place un service ... – meandmycode

Répondre

1

Mise à jour: alors que cela ne s'est pas vraiment effondré, il a fini par produire un conteneur IoC pauvre. J'ai fini juste de remplacer tous ces:

UnitOfWorkFactory.Create(); 

avec la Common Service Locator généralisée mise en œuvre:

Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IUnitOfWork>(); 

Cela m'a permis de créer une bibliothèque qui utilise l'injection de dépendance sans forcer tous les utilisateurs à utiliser le même cadre IoC .


Peut-être que je devrais utiliser une usine très simple où je peux définir un rappel? Il pourrait avoir un ensemble de méthodes statiques dessus comme ceci:

public static class UnitOfWorkFactory 
{ 
    private static Func<IUnitOfWork> FactoryMethod; 

    public static IUnitOfWork Create() 
    { 
     if (UnitOfWorkFactory.FactoryMethod == null) 
     { 
      throw new InvalidOperationException("..."); 
     } 

     return UnitOfWorkFactory.FactoryMethod(); 
    } 

    public static void SetFactoryMethod(Func<IUnitOfWork> factory) 
    { 
     UnitOfWorkFactory.FactoryMethod = factory; 
    } 
} 

Où cela se brise-t-il?

+0

Puisqu'il n'y a pas eu une meilleure solution je suppose que je roule avec ceci. Je serais toujours intéressé d'entendre où cela tombe en panne ou si quelqu'un a une autre perspective. – mckamey

0

Je suggère d'utiliser un modèle Vistor pour découvrir les implémentations de l'interface IUnitOfWork. A l'intérieur de l'instance repo, une fabrique de découverte trouve le worker et le crée.

+0

Je ne vois pas comment cela faciliterait la détermination de l'implémentation de * which * 'IUnitOfWork' que je veux. Le code qui l'utilise sera le même pour toutes les implémentations, sinon je ne ferais qu'instancier le 'IUnitOfWork' que je veux. – mckamey

+0

En utilisant un ou plusieurs attributs et un localisateur d'exécution comme visiteur, vous pouvez marquer les implémentations avec des métadonnées qui permettent à votre usine de choisir le meilleur ajustement. –

+0

Il n'y a rien pour l'éteindre. Chaque instanciation dans la logique est exactement la même (par exemple votre exemple sans passer dans "foo") parce que c'est à un niveau de configuration à l'échelle de l'application que le mécanisme de stockage est choisi. C'est beaucoup plus analogue au modèle ASP.NET Provider. – mckamey

Questions connexes