【问题标题】:How do I use sturcturemap to pass two different implementations of a single interface into a constructor?如何使用 sturcturemap 将单个接口的两个不同实现传递给构造函数?
【发布时间】:2010-09-02 14:06:22
【问题描述】:

我有一个带有两个接口的构造函数,它们是同一个接口,但需要不同的实现:

public class Foo
{
    public Foo(IBar publicData, IBar privateData)
    {
    }
}

我想要发生的是,结构映射将 IBar 的具体实现作为 class PublicDataclass PrivateData 传递给不同的参数。这可能吗?

更新

其实要确保有足够的信息:

我正在使用的真实类如下所示:

public abstract class EFRepository<T> : IRepository<T>
{
    protected EFRepository(IUnitOfWork publicUnitOfWork, 
                           IUnitOfWork privateUnitOfWork)
    {

    }
}

EFRepository 的实现可能如下所示:

public partial class ClaimRepository: EFRepository<Claim>, IClaimRepository
{
    public ClaimRepository(IUnitOfWork publishedUnitOfWork, 
                          IUnitOfWork unpublisedUnitOfWork) 
           : base(publishedUnitOfWork, unpublisedUnitOfWork)
    {
    }
}

因此,当我从结构映射中请求 IClaimRepository 的实例时,我希望为实现提供正确的工作对象单元,在我的实例中,它们本质上是两个不同的数据库,因此它是具有不同连接字符串的相同代码。

【问题讨论】:

    标签: .net structuremap ioc-container


    【解决方案1】:

    尚未编译测试,但原则上应该可以工作:

    For<IBar>.Add<PublicData>.Named("public");
    For<IBar>.Add<PrivateData>.Named("private");
    
    For<IFoo>.Use<Foo>()
      .Ctor<IBar>("publicData").Is(d => d.TheInstanceNamed("public"))
      .Ctor<IBar>("privateData").Is(d => d.TheInstanceNamed("private"));
    

    编辑: 按照惯例,可以使用IRegistrationConvention

    public class FooConvention : IRegistrationConvention
    {
      static readonly Type PluginType = typeof(IFoo);
    
      public void Process(Type type, Registry registry)
      {
         if (type.IsAbstract || !type.IsClass || !PluginType.IsAssignableFrom(type))
           return;
    
          registry.For(PluginType).Add(type)
             .CtorDependency<IBar>("publicData")
             .IsNamedInstance("public")
             .CtorDependency<IBar>("privateData")
             .IsNamedInstance("private");
      }
    }
    

    约定将在扫描中应用

    Scan(scan => 
    {
      scan.AssemblyContainingType<IFoo>();
      scan.Convention<FooConvention>();
    }
    

    有关详细信息,请参阅 SM 文档中的 Scanning Assemblies section

    【讨论】:

    • 有没有办法可以将其应用于基于约定的系统?我宁愿不必手动连接我所有的存储库。
    【解决方案2】:

    如下设置配置:

    For<IFoo>.Use<Foo>();
    For<IBar>.Use<IBar>();
    

    然后获取实例如下:

    IBar privateData = ObjectFactory.GetInstance<IBar>();
    IBar publicData = ObjectFactory.GetInstance<IBar>();
    
    IFoo foo = ObjectFactory
        .With<IBar>(publicData)
        .With<IBar>(privateBar)
        .GetInstance<IFoo>();
    

    这只是一个建议。我的立场是正确的:-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 2012-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多