I have a pretty straightforward generic repository:
public interface IRepository<TEntity, TNotFound>
where TEntity : EntityObject
where TNotFound : TEntity, new()
{
IList<TEntity> GetAll();
TEntity With(int id);
TEntity Persist(TEntity itemToPersist);
void Delete(TEntity itemToDelete);
}
I want to define a contract for a repository for the type Term
without any special behaviour. So it looks like this:
public class TermNotFound : Term
{ public TermNotFound() : base(String.Empty, String.Empty) { } }
public interface ITermRepository : IRepository<Term, TermNotFound> { }
Now for testing, I want to create an in-memory implementation of the generic repo, so I have this (not finished for brevity):
public class InMemoryRepository<TEntity, TNotFound> : IRepository<TEntity, TNotFound>
where TEntity : EntityObject
where TNotFound : TEntity, new()
{
private IList<TEntity> _repo = new List<TEntity>();
public IList<TEntity> GetAll()
{
return this._repo;
}
public TEntity With(int id)
{
return this._repo.SingleOrDefault(i => i.Id == id) ?? new TNotFound();
}
public TEntity Persist(TEntity itemToPersist)
{
throw new NotImplementedException();
}
public void Delete(TEntity itemToDelete)
{
throw new NotImplementedException();
}
}
It's not hard to see how I want it to work. For my tests, I want the generic InMemoryRepository
implementation to be injected to create my ITermRepository
.
Well, I can't get StructureMap to do it. I have tried using WithDefaultConventions
and ConnectImplementationsToTypesClosing(typeof(IRepository<,>))
in the scanner without success. What can I try next?
Your InMemoryRepository
doesn't implement ITermRepository
interface. That's why you can't connect them.
The best thing you could do with what you have is injecting InMemoryRepository<Term, TermNotFound>
for IRepository<Term, TermNotFound>
.
If you really need to inject ITermRepository
, then you'll need to have another repository class inheriting from InMemoryRepository
and implementing ITermRepository
:
public class InMemoryTermRepository
: InMemoryRepository<Term, TermNotFound>, ITermRepository
{
}
Now you can connect ITermRepository
to InMemoryTermRepository
using:
.For<ITermRepository>().Use<InMemoryTermRepository>()
If you have many interfaces like ITermRepository
, you could create a StructureMap convention, to connect I...Repository
to InMemory...Repository
. The default convention is to connect IClass
to Class
.