有没有一种简单的方法可以向温莎城堡注册静态闭包?

2024-03-09

我一直在尝试使用命名委托而不是单一方法接口。这对于代码大小有一些优势,我们可以从以下内容开始(删除了一些换行符,以免夸大情况):

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

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

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


简短回答

您正在尝试使 DI 容器(温莎城堡)执行function构图,但实际上是针对object作品。这只会给你带来很多摩擦。我的猜测是,使用其他容器您也会获得相同的体验。

DI 容器是围绕面向对象的概念设计的 - 特别是 SOLID。它们非常符合这些原则,因为它们的设计是基于对构造函数注入和自动装配等事物的固有理解。

更实用的方法没有什么问题,但我还没有看到围绕函数组合而不是对象组合构建的 DI 容器。

长答案

由于多种原因,使用委托作为 DI 的一般原则在静态类型语言(至少在 .NET 中)中往往会出现问题。从概念上讲,这种方法没有任何问题,因为delegate 可以被认为是一个匿名角色接口 http://blog.ploeh.dk/2009/05/28/DelegatesAreAnonymousInterfaces.aspx。然而,由于类型歧义,它往往变得笨拙。

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

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

public delegate IEnumerable<Product> DGetProducts();

然而,如果你走那条路,那就一无所获。仍必须为每个角色定义“角色委托”。与定义类似的接口相比,很明显,唯一的节省是几个尖括号和显式方法定义:

public interface IProductSource { IEnumerable<Product> GetProducts(); }

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有没有一种简单的方法可以向温莎城堡注册静态闭包? 的相关文章

  • 如何在类文件中使用BackGroundWorker?

    我的program cs调用mdi父frmMain frmMain 然后根据用户操作打开不同的子表单 所有的处理逻辑都写在BusinessLogic cs中 frmMain 在加载时调用 BusinessLogic cs 的方法来初始填充数
  • MVVM ViewModel 很多属性

    我是 MVVM 新手 正在开发一个应用程序 我有一个包含很多属性的表单视图 大约 50 个 我不能将它们分离到用户控件中 因为这会破坏 mvvm 原则 我无法将它们分成模型 因为它们包含逻辑 属性更改 错误更改这些都不是 poco 类 并且
  • 从 SortedList 或 SortedDictionary 获取第 i 个值

    我有一个排序的对象集合 它可以是 SortedList 或 SortedDictionary 我将主要使用它来阅读 因此增加性能并不那么重要 我怎样才能得到第i个值 所以例如当我的集合中有数字 1 2 3 4 5 并且我想要中位数 本例中为
  • 多线程调试技术

    我想知道是否有人知道多线程应用程序调试技术的一个很好的调查 理想情况下 我正在寻找基于案例的分析 死锁 饥饿 损坏的共享状态 Net 特定的或通用的 我不知道有哪篇文章或书籍可以满足您的需求 因此这是我从 12 年 Windows 多线程调
  • 在VB.net中动态添加用户控件

    我在 Vb net Windows 应用程序 中制作了自定义 UserControl 如何将其动态添加到表单中 UserControl 本质上只是另一个类 它继承自 Control 因此您可以使用控件执行各种操作 但除此之外它只是一个类 因
  • 如何在应用程序目录层次结构中构建接口?

    将它们全部放在一个单独的文件夹结构中还是与实现它们的类一起放置 切勿将接口与实现它们的类放在一起 除非这些类满足以下要求 这样做将引入一个紧耦合在接口和实现者之间 如果不同时引用实现者 您将无法创建该接口的其他实现 你基本上有两个选择 将接
  • 将浮点型转换为双精度型

    我正在尝试转换Single to Double同时保持原来的价值 我找到了以下方法 Single f 5 2F Double d1 f 5 19999980926514 Double d2 Double Parse f ToString 5
  • .NET 的 C 代码解析器

    有谁知道 NET 的 C 解析器库吗 我打算将 C 代码解析为某种形式的对象图 这样我就可以将其转换为不同的语言 ANTLR 可以做你想做的事 它有一个 C 预处理器和 ANSI C 语法 https github com antlr gr
  • 替换字符串中的换行符 C#

    如何在 C 中替换字符串中的换行符 使用替换为Environment NewLine myString myString Replace System Environment NewLine replacement text add a l
  • System.Windows.Threading.Dispatcher.Invoke(System.Delegate, System.Object[]) 何时添加?

    使用我的应用程序的一些人似乎越来越 System MissingMethodException Method not found System Object System Windows Threading Dispatcher Invok
  • 与仅调用依赖函数/类相比,在 FastAPI 中使用 Depends 有哪些优点?

    FastAPI 提供了way https fastapi tiangolo com tutorial dependencies 通过其自己的依赖关系解析机制来管理依赖关系 例如数据库连接 它类似于一个pytest夹具系统 简而言之 您在函数
  • 如何获取运行或段落的高度

    我找到了Run or Paragraph in FlowDocument现在我需要知道HEIGHT of it i e while navigator CompareTo flowDocViewer Document ContentEnd
  • ASP.NET 3.5 更新至 4.0 -> Sys.WebForms.PageRequestManager 未定义

    正如标题所示 我最近将包含 UpdatePanels 和类似 AJAX 技术的 ASP NET 3 5 应用程序更新为 ASP NET 4 0 不幸的是 UpdatePanel 不再起作用 整页回发使一切都变得糟糕 Web config 文
  • 为什么 Java 和 .NET 中的字符串不能是可变的?

    为什么他们决定制作String在 Java 和 NET 以及其他一些语言 中是不可变的 他们为什么不让它可变呢 根据有效的Java http www oracle com technetwork java effectivejava 136
  • .NET 中的错误和异常有什么区别?

    您能向我解释一下错误和异常之间的区别吗 一个例外是利用语言语义的类 正如其他人所说 异常会中断堆栈的执行 直到被捕获 一个例外can用于传达错误 但更一般地用于传达发生了异常情况 另一方面 错误可能是异常的 也可能不是异常的 错误有以下几种
  • 了解 C# 中的协变和逆变接口

    我在一本有关 C 的教科书中遇到过这些内容 但我很难理解它们 可能是由于缺乏上下文 对于它们是什么以及它们有什么用处 是否有一个很好的简洁解释 编辑以澄清 协变接口 interface IBibble
  • GetEventLogs() 返回没有设置事件日志?

    采取以下 C 代码 EventLog eventLogs eventLogs EventLog GetEventLogs computername foreach EventLog evt in eventLogs statusMessag
  • 多线程 Web 应用程序

    我知道有很多情况都是在应用程序中使用多线程的好例子 但是什么时候最好在 net Web 应用程序中使用多线程 Web 应用程序几乎肯定已经由托管环境 IIS 等 实现多线程化 如果您的页面受 CPU 限制 并且想要使用多个核心 那么可以说多
  • 打印“X”个字符数与“X”字符串长度的所有可能组合(暴力破解)

    我正在尝试编写一个单词组合生成器 我的意思是打印 X 个字符数与 X 字符串长度的所有可能组合 首先 我需要说的是 我在 StackOverFlow 中看到了一个关于这个问题的问题 其中有很多单词生成器的答案来执行此操作 在不同的语言上 但
  • SecurityAction.RequestMinimum 在 .Net 4.0 中已过时

    最近 我们的 Net 客户端库正在升级以针对 Net 4 0 进行编译 将目标框架更改为4 0后 应用程序出现一些编译错误 In AssemblyInfo cs assembly SecurityPermission SecurityAct

随机推荐