6

Il semble y avoir beaucoup d'exemples sur l'implémentation du pattern Repository pour Linq to SQL. La plupart d'entre eux avec IRepository et DI; Certains ont mis en place l'Unité de Travail et d'autres pas. J'ai essayé de lire comme la plupart des résultats retournés par les recherches sur SO et Google sur les modèles de dépôt Linq to SQL. Néanmoins, je n'ai pas encore trouvé une solution complète.Modèle de référentiel avec Linq to SQL utilisant IoC, Injection de dépendances, Unité de travail

De mes lectures, je l'ai mis en place un modèle référentiel comme indiqué ci-dessous:

repository pattern

J'utilise DI pour enregistrer des interfaces sur lesquelles les dépôts sont dépendu:

this.container.RegisterType<IConnectionStringFactory, ConnectionStringFactory>(new ContainerControlledLifetimeManager(), 
    new InjectionConstructor(connectionString)); 
this.container.RegisterType<IDataContextFactory, DataContextFactory>(); 

mise en œuvre du modèle de stockage:

public interface IPrivilegeRepository : IRepository<PrivilegesEntity> 
{ 
    IList<MenuModel> GetRootMenu(); 
    IList<MenuModel> GetChildMenu(int parentId); 
} 

public class PrivilegeRepository : Repository<PrivilegesEntity>, IPrivilegeRepository 
{ 
    #region IPrivilegeRepository Members 

    public IList<MenuModel> GetRootMenu() 
    { 
     return FindAll(menu => menu.ParentId == null) 
      .OrderBy(menu => menu.SortOrder) 
      .Select(c => EntityMapper.Privileges.ToBusinessObject(c)) 
      .ToList(); 
    } 

    public IList<MenuModel> GetChildMenu(int parentId) 
    { 
     return FindAll(menu => menu.ParentId == parentId) 
      .OrderBy(menu => menu.SortOrder) 
      .Select(menu => EntityMapper.Privileges.ToBusinessObject(menu)) 
      .ToList(); 
    } 

    #endregion 

    public PrivilegeRepository(IDataContextFactory dataContextFactory) 
     : base(dataContextFactory) 
    { 
    } 
} 

interface générique IRepository:

public interface IRepository<T> where T : class 
{ 
    IEnumerable<T> All(); 
    IEnumerable<T> FindAll(Expression<Func<T, bool>> exp); 
    T Single(Expression<Func<T, bool>> exp); 
    T First(Expression<Func<T, bool>> exp); 
} 

classe du référentiel est mis en œuvre comme ci-dessous avec les implémentations de IRepository (non représenté) et d'avoir une dépendance à l'égard IDataContextFactory qui DI prend en charge:

public class Repository<T> : IRepository<T> where T : class 
{ 
    public Repository(IDataContextFactory dataContextFactory) 
    { 
     this.dataContextFactory = dataContextFactory; 
    } 
} 

Référentiels sont consommés en utilisant IoC:

PrivilegeRepository repository = container.Resolve<PrivilegeRepository>(); 

Je conséquence le retour des requêtes en tant que collection d'objets d'affaires afin d'éviter la dépendance sur Lin q à SQL sur les couches d'application où je consomme le référentiel. Le scénario ci-dessus fonctionne correctement avec mon application WPF qui utilise le modèle MVVM. J'ai des classes ViewModel aks Presenter qui ne dépendent pas des classes générées par Linq-SQL.

Comment puis-je étendre ce modèle afin de pouvoir enregistrer des données dans la base de données. Je souhaite renvoyer Business Objects dans le référentiel et les enregistrer. C'est possible? Comment puis-je mettre en œuvre Unité de travail dans un tel scénario.

+0

Vous pouvez regarder le modèle d'enregistrement actif; il couvre les opérations CRUD complètes ainsi qu'une capacité d'accès aux requêtes de type dépôt. –

+0

Qu'en est-il d'Entity Framework livré avec VS2010? – Raj

+0

@Raj Je pense que vous avez manqué le fait qu'il veut être ORM indépendant. – Novus

Répondre

1

Eh bien c'est un problème que j'ai vu beaucoup de fois. Vous voulez que le découplage de vos objets métier se fasse à partir de votre stratégie de stockage de données. Comme vous faites une projection sur vos objets métier, vous perdez beaucoup de fonctionnalités intéressantes d'avoir un référentiel (vous pouvez retourner IQueryable par exemple en utilisant une exécution différée). La seule façon de l'implémenter est de donner à votre Repository une dépendance envers un IMapper<BusinessObject> par exemple. De cette façon, vous pouvez mapper votre objet métier à l'objet dont votre référentiel a besoin pour stocker quelque chose mais en laissant l'abstraction en place, car vos objets métier restent ignorants.

5

Here is an answer of mine to a similar question.

L'idée de base est que référentiel générique interfaces ne fonctionnent pas si bien, mais référentiel générique implémentations grand travail. Il utilise LINQ to SQL comme exemple ORM et devrait fournir un aperçu de votre question.

Assurez-vous de lire la réponse de Paul, en particulier les commentaires.