问题描述
具有如下设置的接口:
public interface IRepository { };
public interface IFirstRepository : IRepository { };
public interface ISecondRepository : IRepository { };
public interface IThirdRepository : IRepository { };
以及需要一些但不是全部这些存储库的Controller:
public class TestController : BaseController
{
private IFirstRepository mFirstRepository;
private ISecondRepository mSecondRepository;
// Standard DI for MVC
public TestController(IFirstRepository first,ISecondRepository second)
{
mFirstRepository = first;
mSecondRepository = second;
}
}
BaseController
如下:
public class BaseController : Controller {
public IEnumerable<IRepository> GetRepos()
{
// One solution is to use reflection
// to get all properties that are IRepositories.
// Something along the lines of;
return typeof(this).GetProperties().Where(prop=>prop is IRepository);
// But is there a way to use the AutoFac context
// to get the repos,rather than use reflection?
// it surely already has that info since it
// was able to call the constructor correctly?
}
}
BaseController
是否可以利用AutoFac上下文和现有信息来获取IRepository
请求的TestController
实例的集合? >
Autofac肯定已经有了该信息,因为它能够使用正确的实例调用构造函数。
解决方法
开箱即用的方法并不容易。如果您发现自己处于这种情况,则通常意味着您遇到了界面设计问题。 There's an FAQ walking through an example of why this is,as well as some options.
如果确实需要这样做,那么我可能会考虑添加metadata to each of the registrations,其中每个需要该特定存储库的控制器都有一个元数据条目,然后使用{{3 }}。同样,metadata filter attribute将逐步进行介绍并显示示例。
但是如果在该系统中运行的是 me ...,我将退后一步,看看我的界面设计,以了解如何一开始就摆脱使用此类过滤器的麻烦。如果不能均等地对待它们(Liskov替换原理),则表明需要使用不同的接口。