2015-03-07 4 views
0

Я использую Entity Framework с DDD.Зависимость между репозиториями

У меня есть следующие лица: лица, Клиент, работник

Лицо является абстрактным. Клиент и сотрудник наследуют человека. У человека есть ссылки на адрес (список) лица.

Должен ли я иметь хранилище для каждого типа или только для каждого конкретного типа? (Just Customer and Employee)

Могу ли я иметь лицо-репозиторий, тогда репозитории Клиента и Сотрудника зависят от него внутри, чтобы избежать избыточного кода? (Использование DI путем впрыска конструктора)

ответ

1

Это не значит, дать полную структуру приложения, но хорошую основу для разработки того, что вам может понадобиться при работе с различными Хранилища и Наследование и т.д.

// Model stuff... 
public interface IBaseEntity 
{ 
    [Key] 
    int Id { get; set; } 
} 

public abstract class BaseEntity : IBaseEntity 
{ 
    [Key] 
    public virtual int Id { get; set; } 

    // Add some extra fields for all Models that use BaseEntity 
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
    [Display(Name = "Last Modified")] 
    public virtual DateTime LastModified { get; set; } 

    [ConcurrencyCheck] 
    [Timestamp] 
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
    public virtual byte[] Timestamp { get; set; } 
} 

public class Person : BaseEntity 
{ 
    // Person Model here... 
} 

public class Employee : Person 
{ 
    // Extra Employee Model items here 
} 

public class Customer : Person 
{ 
    // Extra Customer Model items here 
} 
// End Model stuff 

// Repository stuff... 
public interface IRepository<T> where T : class 
{ 
    IQueryable<T> GetAll(); 
    T GetById(int? id); 
    T Add(T entity); 
    void Update(T entity); 
    void Delete(T entity); 
    void Delete(int id); 
    void Commit(); // To save changes rather than performing a save after each Add/Update/Delete etc. 
} 

public class EFRepository<T> : IRepository<T> where T : class, IBaseEntity 
{ 
    public virtual IQueryable<T> GetAll() 
    { 
     return DbSet.AsQueryable<T>(); 
    } 

    public virtual T GetById(int? id) 
    { 
     var item = DbSet.Find(id); 
     return item; 
    } 

    public virtual T Add(T entity) 
    { 
     DbEntityEntry dbEntityEntry = DbContext.Entry(entity); 
     if (dbEntityEntry.State != EntityState.Detached) 
     { 
      dbEntityEntry.State = EntityState.Added; 
     } 
     else 
     { 
      DbSet.Add(entity); 
     } 
     // SaveChanges() - removed from each DbSet, so can call on all changes in one transaction. 
     // Using Unit Of Work Pattern. Can still use it here though if wished. 
     return entity; 
    } 
    // And so on for each storage method. 
} 

public interface IEmployeeRepository: IRepository<Employee> 
public interface ICustomerRepository: IRepository<Customer> 

public class EmployeeRepository : EFRepository<Employee>, IEmployeeRepository 
public class CustomerRepository : EFRepository<Customer>, ICustomerRepository 
// End Repository stuff 

в принципе вы можете добавить новые модели и их репозиториев, объявив интерфейсы и классы практически ничего внутри них. Все наследуется от базовой функции crud и т. Д. Вам нужно только добавить новые методы для получения записей из базы данных в особых случаях для добавляемой модели - например, FindEmployeeByHairColor (цвет), все остальные EF Gets, Finds и т. Д. Одинаковы независимо от типа.

Это может быть очень глубоким, используя Службы, чтобы обеспечить доступ к основным методам в Хранилищах, добавить шаблон «Единица работы», чтобы объединить несколько DbSets в одну транзакцию и так далее.

Но использование этого типа макета позволяет мне вводить в каждый уровень конкретный репозиторий/службу, которую я хочу использовать, и сохраняет всю логику в одном классе, который используется повторно во всем, что использует аналогичную логику.

Надеюсь, это поможет.

1

У меня просто были бы хранилища для клиентов и сотрудников.

Если существует общая логика между ними, инкапсулируйте ее в абстрактном базовом классе и унаследовать от нее репозитории.

Таким образом, вы бы в конечном итоге с такого рода структуры:

public interface ICustomerRepo { } 

public interface IEmployeeRepo { } 

public abstract class PersonRepoBase<T> { } 

public class CustomerRepo : PersonRepoBase<Customer>, ICustomerRepo { } 

public class EmployeeRepo : PersonRepoBase<Employee>, IEmployeeRepo { } 
Смежные вопросы