我一直在尝试使用命名委托而不是单一方法接口。这对于代码大小有一些优势,我们可以从以下内容开始(删除了一些换行符,以免夸大情况):
public interface IProductSource
{
IEnumerable<Product> GetProducts();
}
public class DataContextProductSource : IProductSource
{
private readonly DataContext _DataContext;
public DataContextProductSource(DataContext dataContext)
{
if (dataContext == null) throw new ArgumentNullException("dataContext");
_DataContext = dataContext;
}
public IEnumerable<Product> GetProducts()
{
return _DataContext.Products.AsEnumerable();
}
}
to:
public delegate IEnumerable<Product> DGetProducts();
public static class DataContextFunctions
{
public DGetProducts GetProducts(DataContext dataContext)
{
if (dataContext == null) throw new ArgumentNullException("dataContext");
return () => dataContext.Products.AsEnumerable();
}
}
这基本上是利用了这样一个事实:一旦你在依赖注入方面走得足够远,很多类就变得只不过是闭包。这些类可以替换为返回 lambda 的函数。整个相关函数集(不需要封装任何可变状态,但可以使用“标准”依赖注入中的类来表达),然后可以汇总到静态类(或 VB 术语中的“模块”)中。
这一切都很好,但我无法找到向温莎城堡注册这些静态方法的最佳方法。没有依赖关系的方法很简单:
Component.For<DGetIntegers>().Instance(Integers.GetOneToTen)
但是上面的 DataContextFunctions.GetProducts 有一些依赖性。我发现注册这个的最好方法是:
Component.For<DGetProducts>().UsingFactoryMethod(
kernel => DataContextFunctions.GetProducts(kernel.Resolve<DataContext>())
这可能会变得非常冗长,并且显然必须直接向内核询问每种依赖项类型有点违背了这一点。在我看来,容器需要的所有静态信息都是可用的,所以应该可以做到这一点。
问题是,温莎城堡(或任何其他容器)是否有一种我错过的简单方法来做到这一点,或者是否出现了技术问题,或者它是否是一个太小众的用例而无法包含在内?