Пользовательская конструкция с открытыми дженериками в StructureMap - PullRequest
0 голосов
/ 02 ноября 2010

Я знаю, что для структуры карты вы можете зарегистрировать универсальные типы, указав следующее:

StructureMapConfiguration 
   .For(typeof(IRepository<>)) 
   .Use(typeof(RepositoryImplementation<>));

Когда вызывается ObjectFactory.GetInstance<IRepository<Entity>>(), возвращается соответствующая реализация RepositoryImplementation<Entity>.

Но что, если я хочу упакованную версию хранилища? Версия, которая также реализует IRepository<Entity> - скажем, CachedRepository<Entity>, которая имеет конструктор, который принимает реализацию IRepository<TEntity> ctor: CachedRepository(IRepository<Entity> innerRepository).

Как мне получить structmap для возврата CachedRepository<Entity> при запросе IRepository с конкретным RepositoryImplementation в качестве innerRepository?

Ответы [ 2 ]

1 голос
/ 03 ноября 2010

Один из подходов заключается в создании пользовательского перехватчика типа:

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

, а затем зарегистрируйте его с помощью:

var container = new Container(x =>
{
    x.For(typeof (IRepository<>)).Use(typeof (RepositoryImplementation<>));
    x.RegisterInterceptor(
      new CacheMyRepos(typeof(IRepository<>), typeof(CachedRepository<>)));
});
0 голосов
/ 03 ноября 2010

Должен ли CachedRepository<Entity> работать с какой-либо конкретной реализацией, или безопасно связать его с RepositoryImplementation<Entity>?Если это может быть связано, это должно сделать трюк:

StructureMapConfiguration
   .For(typeof(IRepository<>)) 
   .Use(typeof(CachedRepository<>));

Затем измените конструктор CachedRepository на CachedRepository(RepositoryImplementation<Entity> innerRepository).

...