Reputation: 1844
I know that for structuremap you can register generic types by specifying the following:
StructureMapConfiguration
.For(typeof(IRepository<>))
.Use(typeof(RepositoryImplementation<>));
When ObjectFactory.GetInstance<IRepository<Entity>>()
is called the corresponding implementation is returned RepositoryImplementation<Entity>
.
But what if I want a wrapped version of the repository? A version that also implements IRepository<Entity>
- lets say CachedRepository<Entity>
that has a constructor that takes an implementation of IRepository<TEntity>
ctor: CachedRepository(IRepository<Entity> innerRepository)
.
How do I get structuremap to return CachedRepository<Entity>
when asking for an IRepository with the concreate RepositoryImplementation as innerRepository?
Upvotes: 0
Views: 278
Reputation: 8557
One approach is to create a custom type interceptor:
public class CacheMyRepos : TypeInterceptor
{
private readonly Type _openTargetType;
private readonly Type _openWrapperType;
public CacheMyRepos(Type openTargetType, Type openWrapperType)
{
_openTargetType = openTargetType;
_openWrapperType = openWrapperType;
}
public object Process(object target, IContext context)
{
var closedWith = target.GetType().GetGenericArguments()[0];
var closedWrapperType = _openWrapperType.MakeGenericType(closedWith);
return Activator.CreateInstance(closedWrapperType, target);
}
public bool MatchesType(Type type)
{
return type.ImplementsInterfaceTemplate(_openTargetType);
}
}
And then register it with:
var container = new Container(x =>
{
x.For(typeof (IRepository<>)).Use(typeof (RepositoryImplementation<>));
x.RegisterInterceptor(
new CacheMyRepos(typeof(IRepository<>), typeof(CachedRepository<>)));
});
Upvotes: 1
Reputation: 8557
Does CachedRepository<Entity>
have to work with any concrete implementation, or is it safe to tie it to RepositoryImplementation<Entity>
? If it can be tied, this should do the trick:
StructureMapConfiguration
.For(typeof(IRepository<>))
.Use(typeof(CachedRepository<>));
Then change the CachedRepository constructor to CachedRepository(RepositoryImplementation<Entity> innerRepository)
.
Upvotes: 0