gpt4 book ai didi

.net - 有没有一种简单的方法可以向 CaSTLe Windsor 注册静态闭包?

转载 作者:行者123 更新时间:2023-12-04 13:24:36 24 4
gpt4 key购买 nike

我一直在尝试使用命名委托(delegate)而不是单方法接口(interface)。这对代码大小有一些好处,我们可以从(删除一些换行符以免夸大情况):

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();
}
}

到:
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();
}
}

这基本上是利用了这样一个事实,即一旦依赖注入(inject)走得足够远,很多类就变成了闭包。这些类可以替换为返回 lambda 的函数。整套相关函数(不需要封装任何可变状态,但可以使用“标准”依赖注入(inject)中的类来表达),然后可以汇总到静态类(或 VB 用语中的“模块”) .

这一切都很好,但是我很难找到将这些静态方法注册到 CaSTLe Windsor 的最佳方法。没有依赖关系的方法很简单:
Component.For<DGetIntegers>().Instance(Integers.GetOneToTen)

但是我们上面的 DataContextFunctions.GetProducts 有一些依赖关系。我发现注册这个的最好方法是:
Component.For<DGetProducts>().UsingFactoryMethod(
kernel => DataContextFunctions.GetProducts(kernel.Resolve<DataContext>())

这可能会变得非常冗长,并且显然必须直接向内核询问每种依赖关系类型有点违背了这一点。在我看来,容器应该需要的所有静态信息都是可用的,所以应该可以做到这一点。

问题是,CaSTLe Windsor(或任何其他容器)是否有一种我错过的简单方法来做到这一点,或者是否出现了技术问题,或者它只是一个太小众的用例而无法包含在内?

最佳答案

简答

您正在尝试使 DI 容器(温莎城堡)执行功能组合,但它实际上是针对对象组合的。那只会给你带来很多摩擦。我的猜测是,您将获得与其他容器相同的体验。

DI 容器是围绕面向对象的概念设计的——尤其是 SOLID。它们非常适合这些原则,因为它们的设计具有对构造函数注入(inject)和 Autowiring 等事物的固有理解。

功能更强大的方法没有错,但我还没有看到围绕函数组合而不是对象组合构建的 DI 容器。

长答案

由于几个原因,将委托(delegate)用作 DI 的一般原则在静态类型语言(至少在 .NET 中)往往会出现问题。从概念上讲,这种方法没有任何问题,因为 delegate can be considered as an anonymous Role Interface .但是,由于类型模糊,它往往变得笨拙。

我通常看到的最常见的方法是使用 BCL 的内置委托(delegate),例如 Func<T> , Action<T>等等。但是,您可能有许多不同的消费者依赖 Func<string>在这种情况下,事情变得模棱两可——仅仅因为消费者需要 Func<string>并不意味着他们需要委托(delegate)人担任相同的角色。虽然机械地可能将 DI 与代表一起使用,但会发生 代表隐藏应用程序角色 .角色消失,只剩下机制。

然后,您可以按照 OP 中的建议为每个角色定义自定义委托(delegate),正如该委托(delegate)所建议的那样:

public delegate IEnumerable<Product> DGetProducts();

但是,如果你走那条路,那就什么也得不到。仍然必须为每个角色定义一个“角色代表”。将其与定义类似的接口(interface)进行对比,应该清楚的是,唯一的节省是一对尖括号和一个显式的方法定义:
public interface IProductSource { IEnumerable<Product> GetProducts(); }

这不是很多开销(如果有的话)。

您可能还想看看这个讨论: http://thorstenlorenz.wordpress.com/2011/07/23/dependency-injection-is-dead-long-live-verbs/

关于.net - 有没有一种简单的方法可以向 CaSTLe Windsor 注册静态闭包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7131047/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com