Right now I'm trying to figure out a way to do things smarter, and in the course of doing so all i've managed to do is use a full bottle of excedrin in a single day.
Assume i have an interface called IRepository like so.
public interface IRepository<T>
{
T Get(int id);
void Add(T value);
void Update(T value);
void Delete(T value);
...
}
And assume i have an implementation like
public class NHibernateRepository<T>
{
...
}
Now, all is fine and good, i can do all my basic operations against the repository to support all CRUD functionality, but i may want specialized operations, so assume i have an interface like this:
public interface IUserRepository : IRepository<User>
{
IList<User> GetUsersByRole(Role role);
}
And an implementation like such:
public class UserRepository : NHibernateRepository<User>, IUserRepository
{
....
}
Ok, so that is the basic setup, now there's one more thing that i want to do. I want to have logging and transaction and things like that all transparently. So what i would like to do is use a dependency injection framework like Castle Windsor or StructureMap so that when i ask for IRepository, i'll get it wrapped by a LoggingRepository and a TransactionRepository, both of which implement IRepository.
So, what i want to do is something like this:
IUserRepository repository = container.Resolve< IUserRepository>();
and have it return a user repository that's wrapped in the Logging and Transaction decorators, but i can't think of a way that this will ever work. The only way i can think of getting this to work is by implementing UserRepository like such:
public class UserRepository : DecoratorRepository<T>, IUserRepository
{
protected IRepository<T> Repository { get; set; }
public UserRepository(IRepository<T> innerRepository)
{
Repository = innerRepository;
}
}
This would mean that we would use Dependancy Injection to create a decorated repository and pass that into the constructor of the UserRepository and then use that as the repository in which we run operations against. This would work, but i still don't think it's ideal.
So, my question is, am I right in that this is the only way to do this, or am I not understanding this correctly or just missing something all together. Also, if you have run up against this problem before, how did you solve this problem?