【问题标题】:Custom construction with open generics in StructureMap在 StructureMap 中使用开放泛型的自定义构造
【发布时间】:2010-11-04 00:36:58
【问题描述】:

我知道对于结构映射,您可以通过指定以下内容来注册泛型类型:

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

ObjectFactory.GetInstance&lt;IRepository&lt;Entity&gt;&gt;()被调用时,对应的实现被返回RepositoryImplementation&lt;Entity&gt;

但是如果我想要存储库的打包版本怎么办?一个还实现了IRepository&lt;Entity&gt; 的版本 - 假设CachedRepository&lt;Entity&gt; 有一个构造函数,该构造函数采用IRepository&lt;TEntity&gt; ctor: CachedRepository(IRepository&lt;Entity&gt; innerRepository) 的实现。

在请求 IRepository 并将 concreate RepositoryImplementation 作为 innerRepository 时,如何让结构映射返回 CachedRepository&lt;Entity&gt;

【问题讨论】:

    标签: .net generics structuremap


    【解决方案1】:

    一种方法是创建自定义类型拦截器:

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

    【讨论】:

      【解决方案2】:

      CachedRepository&lt;Entity&gt; 是否必须与任何具体实现一起工作,或者将其绑定到RepositoryImplementation&lt;Entity&gt; 是否安全?如果可以绑定,这应该可以解决问题:

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

      然后将 CachedRepository 构造函数更改为CachedRepository(RepositoryImplementation&lt;Entity&gt; innerRepository)

      【讨论】:

      • 我想将接口保留在构造函数中。通过这样做,我可以稍后将其他逻辑层添加到存储库中。即 CachedRepository -> NotifyingRepository -> LoggingRepository -> TimingRepository -> ActualRepositoryImplementation。通过这样做,我可以将逻辑与我的存储库的实际实现分开
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-16
      • 2016-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多