Прямо сейчас я пытаюсь найти способ сделать что-то умнее, и в ходе этого всего, что мне удалось сделать, это использовать полную бутылку эксцедрина за один день.
Предположим, у меня есть интерфейс, который называется IRepository.
public interface IRepository<T>
{
T Get(int id);
void Add(T value);
void Update(T value);
void Delete(T value);
...
}
И предположим, у меня есть реализация, подобная
public class NHibernateRepository<T>
{
...
}
Теперь все хорошо, я могу выполнять все свои основные операции с хранилищем для поддержки всех функций CRUD, но я могу захотеть специализированных операций, поэтому предположим, что у меня есть такой интерфейс:
public interface IUserRepository : IRepository<User>
{
IList<User> GetUsersByRole(Role role);
}
И такая реализация:
public class UserRepository : NHibernateRepository<User>, IUserRepository
{
....
}
Хорошо, это базовая настройка, теперь я хочу сделать еще одну вещь. Я хочу, чтобы логирование и транзакции и тому подобное были прозрачными. Поэтому я хотел бы использовать среду внедрения зависимостей, такую как Castle Windsor или StructureMap, чтобы при запросе IRepository он был обернут в LoggingRepository и TransactionRepository, которые оба реализуют IRepository.
Итак, я хочу сделать что-то вроде этого:
IUserRepository repository = container.Resolve< IUserRepository>();
и пусть он вернет пользовательский репозиторий, завернутый в декораторы Logging и Transaction, но я не могу придумать, как это сработает. Единственный способ заставить это работать - реализовать UserRepository, например:
public class UserRepository : DecoratorRepository<T>, IUserRepository
{
protected IRepository<T> Repository { get; set; }
public UserRepository(IRepository<T> innerRepository)
{
Repository = innerRepository;
}
}
Это будет означать, что мы будем использовать Dependancy Injection, чтобы создать декорированный репозиторий и передать его в конструктор UserRepository, а затем использовать его в качестве репозитория, в котором мы выполняем операции. Это будет работать, но я все еще не думаю, что это идеально.
Итак, мой вопрос в том, прав ли я, что это единственный способ сделать это, или я не понимаю это правильно или просто что-то упускаю все вместе. Кроме того, если вы столкнулись с этой проблемой раньше, как вы решили эту проблему?