2016-09-22 4 views
0

У меня есть два сложных класс:Override собственности конфликт

public class BaseRepository<EntityType> where EntityType : class 
{ 
    protected northwindDataContext context = new northwindDataContext(); 

    public EntityType Get(object id) 
    { 
     return context.Set<EntityType>().Find(id); 
    } 

    public EntityType Save(EntityType entity) 
    { 
     // Do generic save things 
    } 
} 

public class BaseService<EntityType> where EntityType : class 
{ 
    public BaseRepository<EntityType> repo = new BaseRepository<EntityType>(); 

    public EntityType Get(object id) 
    { 
     // Do generic get entities 
     return repo.Get(id); 
    } 
} 

Тогда у меня есть несколько «услуг» класса, где иногда (не всегда) мне нужно, чтобы «заменить» репозиторий, чтобы добавить некоторые «лишние» funcionality.

public class UserRepository : BaseRepository<User> 
{ 
    public User Get(object id) 
    { 
     // Do specific user get including Role DP 
     return context.Users.Include("Role").Find(id); 
    } 
} 

public class UserService : BaseService<User> 
{ 
    public UserRepository repo = new UserRepository(); 
} 

Используя этот формат экземпляра UserService вызова BaseRepository.Get() вместо UserRepository.Get().

Единственный способ сделать то, что я хочу повторить подобный код:

public class UserService : BaseService<User> 
{ 
    public UserRepository repo = new UserRepository(); 

    public User Get(object id) 
    { 
     // This call to UserRepository.Get() 
     return repo.Get(id); 
    } 
} 

Реальная проблема заключается в том, что у меня есть 29 «Хранилища», так что мне нужно добавить «Get (INT)», «Получить (предикат) "," Сохранить (сущность) "," Сохранить (IEnumerable) "," Удалить (сущность) "и" Удалить (IEnumerable) ", и это делает некий неудобный код.

Есть ли способ заменить свойство «repo» в BaseService, чтобы методы BaseService вызывали подкласс repo?

ответ

3

Это похоже на то, что вы действительно хотите, для поля BaseService<T>.repo (это поле, а не свойство), и я бы отговорил вас от использования публичных полей, но это другое дело), ​​чтобы быть подходящим видом хранилища для типа. Это достаточно легко сделать - просто не создавайте его в BaseService<T>. Вместо этого, передать его в конструктор цепи:

// Type parameter renamed to follow normal .NET naming conventions 
public abstract class BaseService<T> where T : class 
{ 
    private readonly BaseRepository<T> repo; 

    protected BaseService(BaseRepository<T> repo) 
    { 
     this.repo = repo; 
    } 

    public T Get(object id) 
    { 
     // Do generic get entities 
     return repo.Get(id); 
    } 
} 

public class UserService : BaseService<User> 
{ 
    public UserService() : base(new UserRepository()) 
    { 
    } 
} 

В самом деле, если UserService не предоставляет каких-либо другое значение, то, возможно, потребуется только Service<T>, неабстрактный и с общественного конструктор принять репо , Тогда вы просто используете:

var userService = new Service<User>(new UserRepository()); 

например.

+0

Лучшая часть этого - это теперь дружественная к DI. –

+0

Я действительно делаю это, но я не могу переопределить метод Get на UseRepository, если BaseRepository определил «Get». BaseRepository.Get() должен возвращать context.Set (). Только FID (id) Если переопределенное репо не имеет этого метода. – Pythonizo

+0

Спасибо за все. Я разрешаю это с вашей помощью и добавляю «virtual» в BaseService.Get() и «переопределять» в UserService.Get() – Pythonizo

Смежные вопросы