How should I use IoC DI with this repository pattern?
I am using the repository pattern found in the answer to this SO question:
Advantage of creating a generic repository vs. specific repository for each obje开发者_JAVA技巧ct?
Namely, each repository inherits from an abstract base class that contains generic methods like add, delete, etc. and also implements a specific repository interface for any methods that are unique to that repository/entity.
ie.
public class CompanyRepository : Repository<Company>, ICompanyRepository {
...
}
In my business layer I am using Structure Map to get an instance of the repository, but I am unsure how to use it.
// Structure Map initialisation
ObjectFactory.Initialize(
x =>
{
x.For<ICompanyRepository>().Use<CompanyRepository>();
});
resolving an instance:
return ObjectFactory.GetInstance<ICompanyRepository>();
However the instance I get is an interface and not the whole repository implementation. I don't have access to the methods on the base class (Repository<Company>
). What is the usual way to do this?
The key here is to think of Repository<>
solely as an implementation detail. You won't be accessing any methods on it directly; instead, you will expose all methods, including Insert
and Delete
, on the interface:
public interface ICustomerRepository
{
// ...Customer-specific queries...
void Insert(Customer customer);
void Delete(Customer customer);
}
When you implement the interface in CustomerRepository
, you simply have to pass the Insert
and Delete
calls through to the protected methods of Repository<>
as discussed in the original question.
The StructureMap registration you state in the question is exactly what I would expect. The purpose of Repository<>
then is to aid in the implementation of entity-specific interfaces. Keep in mind that the interfaces will always contain the repository's full public API and that should point you in the right direction.
Why not
return ObjectFactory.GetInstance<Repository<Company>>;
? You will have to modify accordingly your ObjectFactory initialization:
// Structure Map initialisation
ObjectFactory.Initialize(
x => {
x.For<Repository<Company>>().Use<CompanyRepository>();
});
EDIT
If you still want to get Repository<Company>
also for ICompanyRepository
, you need to declare a forwarding:
// Structure Map initialisation
ObjectFactory.Initialize(
x => {
x.For<Repository<Company>>().Use<CompanyRepository>();
x.Forward<Repository<Company>, ICompanyRepository>();
});
精彩评论