有关于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:
由于我们采取了略微不同的方法,因此迫切需要解决这个问题。不过,我仍然有兴趣听取理查德的其他建议。
答案 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”,允许在适用时重用相同的查找存储库。
现在有用吗?