在StructureMap中连接通用接口

时间:2010-01-15 16:45:43

标签: c# generics structuremap

有关于StructureMap和泛型的SO有几个问题,我已经阅读了一些关于它的博客文章,但我仍然在努力找出这个特定场景的解决方案。

假设:

public interface ILookup
{
}

public interface ISupplier : ILookup
{
}

public interface ITenant : ILookup
{
}

public class Supplier : ISupplier
{
}

public class Tenant : ITenant
{
}

public interface ILookupRepository<TLookup> where TLookup : ILookup
{
   void DoSomethingWith(TLookup lookup);
}

public class LookupRepository<TLookup> : ILookupRepository<TLookup> where TLookup : ILookup
{
   public void DoSomethingWith(TLookup lookup)
   {
      SaveOrWhatever(lookup);
   }
}

public class SomeClass
{   
   public void ProcessLookup(ILookup lookup)
   {
      // Get hold of a concrete class for ILookupRepository<TLookup> where TLookup is the type of the supplied
      // lookup. For example, if ProcessLookup is passed an ISupplier I want a LookupRepository<ISupplier>.
      // If it's passed an ITenant I want a LookupRepository<ITenant>.

      // var repository = ???

      repository.DoSomethingWith(lookup);
   }
}

如何让StructureMap为SomeClass.ProcessLookup提供相应的LookupRepository<ISupplier>LookupRepository<ITenant>?这可能没有反思吗?我可以选择获得LookupRepository<Supplier>LookupRepository<Tenant>吗?

更新

读过理查德的初步回答后,我意识到我原来的问题并没有很好地表达我的问题(毕竟是星期五!)。我正在处理的不仅仅是ILookup的一个实现,并且希望能够为我提供的类型获得正确的ILookupRepository。我已经更新了上面的问题,希望能更准确地反映我的要求。

更新2:

由于我们采取了略微不同的方法,因此迫切需要解决这个问题。不过,我仍然有兴趣听取理查德的其他建议。

1 个答案:

答案 0 :(得分:1)

[编辑初始回复未回答真实问题]

当我需要做类似的事情时,我使用命名实例。不幸的是,我想不出任何简单的方法来做你需要的东西而不引入非通用接口。非通用接口看起来像这样(并且希望实际上不会公开):

public interface ILookupRepository
{
   void DoSomethingWith(object lookup);
}

使ILookupRepository从非泛型ILookupRegistry接口继承。然后在StructureMap 2.5.4中你可以这样做:

 For<ILookupRepository>().Add<LookupRepository<Supplier>>()  
    .Named(typeof(Supplier).FullName);
 For<ILookupRepository>().Add<LookupRepository<Tenant>>()  
    .Named(typeof(Tenant).FullName);

然后使用

在您的方法中获取查找存储库
var repo = ObjectFactory.GetInstance<ILookupRepository>(lookup.GetType().FullName);

注意:如果ILookup接口提供确定类型的机制,可能会更好(如果可能)。例如。具体的Tenant(或从中继承的任何东西)将返回“ITenant”,允许在适用时重用相同的查找存储库。

现在有用吗?