我一直在尝试使用命名委托而不是单方法接口.这对代码的大小一定的优势,因为我们可以从(一些换行符删除,以免夸大的情况下)去:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
至:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
这基本上利用了这样一个事实:一旦你使用依赖注入足够远,很多类变得只是闭包.这些类可以用返回lambdas的函数替换.整套相关函数(不需要封装任何可变状态,但在"标准"依赖注入中使用类表示)可以汇总到静态类(或VB术语中的"模块") .
这一切都很好,但我找不到使用Castle Windsor注册这些静态方法的最佳方法.没有依赖关系的方法很简单:
Component.For<DGetIntegers>().Instance(Integers.GetOneToTen)
Run Code Online (Sandbox Code Playgroud)
但是我们上面的DataContextFunctions.GetProducts有一些依赖关系.我发现注册这个的最好方法是:
Component.For<DGetProducts>().UsingFactoryMethod(
kernel => DataContextFunctions.GetProducts(kernel.Resolve<DataContext>())
Run Code Online (Sandbox Code Playgroud)
这可能会变得非常冗长,显然不得不直接询问内核的每一个依赖类型.在我看来,容器应该需要的所有静态信息都是可用的,因此应该可以这样做. …
.net closures dependency-injection castle-windsor ioc-container