如果在为 MVC 4 设置依赖项解析器之前使用验证,简单注入器会失败

2024-04-23

我们有一个基于 ASP.NET MVC 4 的应用程序,该应用程序已有几年历史,我正在努力消除它的一些技术债务。我正在做的事情之一是引入依赖注入,以便我们可以更好地将业务逻辑与数据访问实现分开,并减少编写隔离单元测试的痛苦。我使用了简单注射器,但遇到了一些问题。

我已经按照简单注入器文档中的 MVC 集成指南 http://simpleinjector.readthedocs.org/en/latest/mvcintegration.html。它描述了这样的初始化过程:

  1. 创建一个容器
  2. 在容器中注册类型
  3. 验证容器(可选)
  4. 覆盖默认的依赖解析器

因此,这是迄今为止在应用程序中实现的方式。为了清楚起见,我删除了日志记录语句,并为上述步骤添加了标记注释:

// 1
var container = new Container();
var webRequestLifestyle = new WebRequestLifestyle();

// 2
container.Register<IOrganizationService>(
    delegate
    {
        var proxy = new OrganizationServiceProxy(
            organizationServiceManagement, clientCredentials);
        proxy.EnableProxyTypes();
        return proxy;
    },
    webRequestLifestyle);

container.RegisterSingle<ILoggerProvider>(LoggerProvider); // static field
container.Register<IExternalLinkRepository, ExternalLinkRepository>(webRequestLifestyle);
container.Register<IQueueRepository, QueueRepository>(webRequestLifestyle);
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.RegisterMvcIntegratedFilterProvider();

// 3
container.Verify(VerificationOption.VerifyAndDiagnose);

// 4
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));

当尝试实例化 MVC 控制器时,上述代码在步骤 3 中失败,抛出异常System.InvalidOperationException: An error occurred when trying to create a controller of type 'MyProject.MyNamespace.MyController'. Make sure that the controller has a parameterless public constructor.

这是有道理的,因为我的控制器是为构造函数注入设置的。例如:

public MyController(ILoggerProvider loggerProvider)
{
    Logger = loggerProvider.Get(GetType());
}

默认的 MVC 控制器激活器不知道如何处理这个问题。然而,我不明白的是为什么Container.VerifySimple Injector 的方法完全命中了 MVC 的默认控制器激活器。容器不应该天生使用简单注入器的依赖解析来测试依赖图吗?查看异常调用堆栈,它起源于System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create,所以它在某些时候肯定超出了简单注入器的范围。

但是,当我交换步骤 3 和 4 的顺序时:

DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
container.Verify(VerificationOption.VerifyAndDiagnose);

它成功验证了容器,并且依赖项注入在应用程序中也按预期工作。这似乎暂时解决了问题。尽管如此,我还是想知道:

  1. 为什么 Simple Injector 使用 MVC 的默认控制器激活器来测试依赖解析?这是预期/记录在任何地方吗?
  2. 首先设置自定义解析器然后验证是否有任何副作用?我这么问是因为这与文档中的指南相反。它似乎按预期工作,如果其中任何一个失败,应用程序无论如何都会崩溃,所以从应用程序的角度来看,这似乎并不重要。

所以,这是一个值得追踪的有趣的事情。作为最后的手段,应用程序尝试处理未捕获的错误Application_Error. The Verify()方法,这是在Application_Start,验证失败时确实抛出了异常,但这被捕获了Application_Error方法(需要弄清楚为什么它没有被记录,但这是一个不同的故事)。所以,调用DependencyResolver.SetResolver从未被制造过。然后,通过管道发出的实际请求将尝试使用默认控制器激活器。而且所发出的请求当然不是向隐藏的控制器发出的,这导致验证失败。

一个控制器也有一个静态构造函数,它缓存了一批只读数据,这些数据不需要为应用程序的每个新请求进行处理。该静态构造函数因错误而崩溃,导致该控制器无法实例化并导致应用程序停止。以更合理的方式缓存数据并删除静态构造函数后,验证进展顺利,并且应用程序在再次根据指南进行 DI 设置时工作正常。

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

如果在为 MVC 4 设置依赖项解析器之前使用验证,简单注入器会失败 的相关文章

随机推荐

  • 如何对异步 API 进行单元测试?

    我已经安装了适用于 Mac 的 Google 工具箱 http code google com p google toolbox for mac 进入 Xcode 并按照说明设置单元测试发现here http code google com
  • Android NDK 链接问题

    我用 NDK 编译了 Sox 等 所以 我拥有所有 Android 友好的共享库 我制造了一个简单的测试文件 http pastebin com rniwQ7Gz它调用 sox 函数 NDK 构建告诉我 undefined referenc
  • 尝试以紧凑模式访问 UITextView 时 iMessage 扩展程序崩溃

    下面是我在 iMessage 应用程序中的完整代码 class MessagesViewController MSMessagesAppViewController IBOutlet weak var messageView UITextV
  • .net Web 应用程序中的异常处理

    我承认 我不关心太多的异常处理 我知道我应该做得更多 但我永远不知道从哪里开始和从哪里停止 我并不懒惰 离得很远 这是因为我对异常处理的矛盾心理感到过度紧张 即使是最小的应用程序中 似乎也有无数个地方可以应用异常处理 但它可能会让人感觉有点
  • Java 中对象序列化和压缩的性能成本

    应用程序不断接收名为Report并将对象放入Disruptor对于三个不同的消费者 在 Eclipse Memory Analysis 的帮助下 每个进程的 Retained Heap SizeReport对象平均为 20KB 该应用程序开
  • 使用 xslt 比较两个 xml 文件?

    我有 2 个 xml 文件 如何使用 xslt 比较两个文件是否相等 如果不等于意味着第二个 xml 中发生了更改 在 XPath 2 0 中你可以简单地使用fn deep equal http www w3 org TR 2005 CR
  • 检测用户何时点击 div 外部

    我正在向用户展示一个模式 灯箱 当用户单击按钮时 模式会显示 页面的其余部分会变暗 平常的东西 不过我想这样做 如果用户单击模式之外的任何元素 我希望模式消失并且页面恢复正常 如何才能做到这一点 我知道我可以为 body 设置一个 oncl
  • 分配不同价值对象的算法建议

    我有以下问题 给定 N 个对象 N 编辑 通过最公平的分配 我的意思是任何两个玩家获得的物体的价值之间的差异是最小的 另一个类似的情况是 我有N个不同价值的硬币 我需要将它们平均分配给M个玩家 有时他们并没有完全分开 我需要找到下一个最佳的
  • 为什么在 Chrome 中定位:粘性不起作用?

    你怎么获得position sticky在职的 我在 Chrome 26 0 1410 43 m 中尝试了以下操作 但它不起作用 thead position webkit sticky position moz sticky positi
  • $routeProvider 不适用于 html5Mode

    我刚刚开始学习 AngularJs 并尝试使用 Angular 路由服务配置部分页面 它适用于哈希格式 但是 当我试图摆脱哈希时 routeProvider 停止工作 JS app config function routeProvider
  • 使用 JavaScript 创建 csv 文件

    有人可以解释一下是否有一种方法可以将 html5 本地存储数据转换为 csv 文件并将其存储在 ipad 中 我有一个带有一些文本字段的 html 页面 当用户单击提交按钮时 它会存储在 html5 本地存储中 然后我需要使用该数据创建一个
  • 了解 3NF:请用简单的英语

    我正在解决一个示例问题 其中我们试图确定以下哪些关系属于第三范式 3NF 以下是我们给出的关系 R1 ABCD ACD gt B AC gt D D gt C AC gt B R2 ABCD AB gt C ABD gt C ABC gt
  • 如何在不缩小的情况下构建 React 的生产版本?

    背景 我或多或少都在关注使用 React 设置本地开发环境的官方指南 https reactjs org tutorial tutorial html setup option 2 local development environment
  • 将新行添加到控制台输出

    在控制台应用程序中 我们将语句写为 Console WriteLine the addition is 0 i 它给出了输出 加法是50 现在我的问题是 我希望答案如下所示 加法是 50 我如何将输出分配给下一行 Console Write
  • 如何使用 Selenium WebDriver 和 Java 单击按钮?

    以下是按钮的 HTML 代码 span span
  • 什么是沙箱?

    我已阅读维基百科文章 http en wikipedia org wiki Sandbox software development 但我不太确定这意味着什么 以及它与版本控制 如果有人可以用非常简单的术语解释什么是沙箱 那将会很有帮助 A
  • 在 WordPress 中查找当前页码

    我在我的 WordPress 模板中添加了以下自定义循环 args array category not in gt array featured cat gt term id posts per page gt 10 post not i
  • 如何找到UITableViewCell的ViewController?

    我需要参考ViewController from a UITableViewCell以显示UIAlertController来自外部班级 我怎样才能找到该参考文献 你可以获得一个实例UIViewController from UITable
  • 适用于 neovim / vim8 的 C# LSP 自动完成客户端

    我尝试了多种方法来使其发挥作用 但似乎没有简单的方法 是的 有大量的插件和配置 但截至 2019 年 10 月 它们无法正常工作 OmniSharp Vim https github com OmniSharp omnisharp vim客
  • 如果在为 MVC 4 设置依赖项解析器之前使用验证,简单注入器会失败

    我们有一个基于 ASP NET MVC 4 的应用程序 该应用程序已有几年历史 我正在努力消除它的一些技术债务 我正在做的事情之一是引入依赖注入 以便我们可以更好地将业务逻辑与数据访问实现分开 并减少编写隔离单元测试的痛苦 我使用了简单注射