Одним из наиболее распространенных способов решения этой проблемы является использование инверсии управления.
Например, у вас есть классы User и Comment, и вы реализовали общий репозиторий IRepository<TDomainObject>
.Это значит, что хранилище User или Comment просто задает параметр TDomainObject:
IRepository<User>
IRepository<Comment>
Позже вы настроиликто реализует IRepository<User>
и IRepository<Comment>
, поэтому, если вы используете что-то вроде Общего локатора служб Microsoft Pattern & Practices, и мы находимся в теле метода commit в вашей единице работы :
foreach(DomainObject some in NewObjects)
{
((IRepository<DomainObject>)ServiceLocator.Current.GetInstance(Type.GetType(string.Format("NamespacesToGenericRepository.IRepository`1[[{0}]]", some.GetType().FullName)))).Add(some);
}
Примечание IRepository<TDomainObject>
имеет контравариантный TDomainObject универсальный параметр, тип которого должен наследовать базовый тип объекта домена, называемый DomainObject , который разрешаетupcast-что-то вроде IRepository<User>
до IRepository<DomainObject>
.
Другими словами, ваша IRepository<TDomainObject>
подпись интерфейса будет выглядеть следующим образом:
public interface IRepository<out TDomainObject>
where TDomainObject : DomainObject
Это просто сводка и / илиподсказка о том, как реализовать размещение конкретного репозитория, чтобы единица работы объектов домена могла управлять объектами любого специализированного объекта домена.
Если вы хотите узнать больше о инверсииконтрольная проверкаэта статья в Википедии:
И, исходя из собственного опыта, я хотел бы предложить вам Виндзорский замок как инверсия контроля рамки выбора: