Custom construction with open generics in StructureMap

不羁岁月 提交于 2019-12-08 09:54:44

问题


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?


回答1:


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<>)));
});



回答2:


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).



来源:https://stackoverflow.com/questions/4079819/custom-construction-with-open-generics-in-structuremap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!