从 MVC 的 DependencyResolver 转换到 AutofacWebApiDependencyResolver - .Current 在哪里?

2023-12-06

我让 AutoFac 与 MVC4 一起正常工作。我正在尝试过渡到 Web API 2。以下是我设置 AutoFac 的方法:

public class AutofacRegistrations
{
    public static void RegisterAndSetResolver()
    {
        // Create the container builder.
        var containerBuilder = new ContainerBuilder();

        // Register the Web API controllers.
        containerBuilder.RegisterApiControllers(Assembly.GetExecutingAssembly());

        //  Only generate one SessionFactory ever because it is expensive.
        containerBuilder.Register(x => new NHibernateConfiguration().Configure().BuildSessionFactory()).SingleInstance();

        //  Everything else wants an instance of Session per HTTP request, so indicate that:
        containerBuilder.Register(x => x.Resolve<ISessionFactory>().OpenSession()).InstancePerApiRequest();
        containerBuilder.Register(x => LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType)).InstancePerApiRequest();

        containerBuilder.RegisterType<NHibernateDaoFactory>().As<IDaoFactory>().InstancePerApiRequest();
        containerBuilder.RegisterType<StreamusManagerFactory>().As<IManagerFactory>().InstancePerApiRequest();

        // Build the container.
        ILifetimeScope container = containerBuilder.Build();

        // Create the depenedency resolver.
        var dependencyResolver = new AutofacWebApiDependencyResolver(container);

        // Configure Web API with the dependency resolver.
        GlobalConfiguration.Configuration.DependencyResolver = dependencyResolver;
    }
}

我非常有信心所有这些都是正确的。当我尝试设置一些测试用例时,我的问题出现了。我的测试用例的基类不是控制器,因此它不会自动传递任何内容。在 MVC4 中我做了以下事情:

[SetUp]
public void SetUp()
{
    HttpSimulator = new HttpSimulator().SimulateRequest();

    Logger = DependencyResolver.Current.GetService<ILog>();
    DaoFactory = DependencyResolver.Current.GetService<IDaoFactory>();
    Session = DependencyResolver.Current.GetService<ISession>();
    ManagerFactory = DependencyResolver.Current.GetService<IManagerFactory>();
}

[TearDown]
public void TearDown()
{
    HttpSimulator.Dispose();
}

不幸的是,没有DependencyResolver.Current在 WebAPI 中。所以我想知道如何正确地做到这一点?

这可以构建,但不正确。我收到消息“会话已关闭!”当我尝试执行测试用例时:

[SetUp]
public void SetUp()
{
    using (var scope = GlobalConfiguration.Configuration.DependencyResolver.BeginScope())
    {
        //  TODO: Consider initializing Helpers during setup to keep this DRY.
        Logger = (ILog)scope.GetService(typeof(ILog));
        DaoFactory = (IDaoFactory)scope.GetService(typeof(IDaoFactory));
        Session = (ISession)scope.GetService(typeof(ISession));
        ManagerFactory = (IManagerFactory)scope.GetService(typeof(IManagerFactory));
    }
}

使用 WebAPI,您不需要访问当前解析器,因为当前依赖范围通常与入站一起提供HttpRequestMessage。该消息还负责生成新的请求范围。

您可以在以下位置查看此代码System.Net.Http.HttpRequestMessageExtensions.GetDependencyScope method.

在 WebAPI 中您会注意到的一件大事是您实际上不需要在全局静态值中设置任何内容- 也就是说,您不需要设置全局配置/解析器,因为现在一切都是基于实例的。

对于测试来说,这意味着:

  • 您的设置将创建一个HttpRequestMessage使用适当的依赖解析器和配置。
  • 您的拆解将处理掉HttpRequestMessage反过来,这将处理依赖范围等。
  • 个别测试将使用HttpRequestMessage.GetDependencyScope()如果他们需要手动解决某些问题,请求消息将用于协调/传递范围。

以更具体的方式,它可能看起来像:

private HttpRequestMessage _request;

[SetUp]
public void SetUp()
{
  var builder = new ContainerBuilder();
  // Register stuff.
  var container = builder.Build();
  var resolver = new AutofacWebApiDependencyResolver(container);

  var config = new HttpConfiguration();
  config.DependencyResolver = resolver;
  config.EnsureInitialized();

  this._request = new HttpRequestMessage();
  this._request.SetConfiguration(config);
}

[TearDown]
public void TearDown()
{
  this._request.Dispose();
}

[Test]
public void Test()
{
  // When you need to resolve something, use the request message
  this._request.GetDependencyScope().GetService(typeof(TheThing));
}

这样做的好处是,您不必在每次测试后与全局配置设置或重置静态值作斗争。

您可能想知道为什么要传递整个请求消息而不仅仅是依赖解析器 - 原因是请求消息负责协调和控制依赖范围的生命周期。否则,当你打电话时GetDependencyScope多次,您将获得多个不同的范围,而不是您期望的相同范围。

从设计角度考虑一些事情:

  • 你可能想要将事物的实际注册放入 Autofac 模块中所以它可以在测试和你的RegisterAndSetResolver方法,而不必担心全局静态数据被篡改。
  • 代替RegisterAndSetResolver修改全局静态配置,您可能会考虑只需将解析器设置为HttpConfiguration连接到其中的对象WebApiConfig.Register methodWebAPI 为您提供了。采取一个HttpConfiguration对象作为参数,并在该对象上设置解析器而不是全局的。
  • 如果您在单元测试中对所有内容进行每次注册,那么您的单元测试可能更接近“集成测试”。您可能会考虑仅查看您正在测试的内容所需的内容,并且使用模拟框架来注册存根,而不是实际注册大量“真实的东西”。

Anyway, HttpRequestMessage是 WebAPI 的出路。

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

从 MVC 的 DependencyResolver 转换到 AutofacWebApiDependencyResolver - .Current 在哪里? 的相关文章

  • ASP.NET MVC 中的经典 ASP (C#)

    我有一个应用程序想要 最终 转换为 ASP NET MVC 我想要进行全面的服务升级 到 ASP NET 但想要使用当前的 ASP 内容来运行当前的功能 这样我就可以在对新框架进行增量升级的同时升级小部分 该站点严重依赖于不太成熟的 VB6
  • OpenCv读/写视频色差

    我试图简单地使用 openCV 打开视频 处理帧并将处理后的帧写入新的视频文件 我的问题是 即使我根本不处理帧 只是打开视频 使用 VideoCapture 读取帧并使用 VideoWriter 将它们写入新文件 输出文件看起来比输入更 绿
  • asp.net 文本框文本模式数字,仅允许数字

    我只是想知道 ASP NET 中是否有一种方法只允许文本框中的数字textmode number 当我使用这个时
  • 为什么我不能用 `= delete;` 声明纯虚函数?

    Intro 纯虚函数使用通用语法声明 virtual f 0 然而 自 c 11 以来 有一种方法可以显式地传达non existence 特殊 成员函数的 Mystruct delete eg default constructor Q
  • 为什么要序列化对象需要 Serialized 属性

    根据我的理解 SerializedAttribute 不提供编译时检查 因为它都是在运行时完成的 如果是这样 那么为什么需要将类标记为可序列化呢 难道序列化器不能尝试序列化一个对象然后失败吗 这不就是它现在所做的吗 当某些东西被标记时 它会
  • C# 中的接口继承

    我试图解决我在编写应用程序时遇到的相当大的 对我来说 问题 请看这个 为了简单起见 我将尝试缩短代码 我有一个名为的根接口IRepository
  • 构造函数中显式关键字的使用

    我试图了解 C 中显式关键字的用法 并查看了这个问题C 中的explicit关键字是什么意思 https stackoverflow com questions 121162 但是 那里列出的示例 实际上是前两个答案 对于用法并不是很清楚
  • .Net Web API 未找到与请求 URI 匹配的 HTTP 资源

    我正在开发 Net Web API 它在调试和本地主机 IIS 上都运行良好 但是当我将其发布到服务器时 它开始给出以下错误 Message 未找到与请求 URI 匹配的 HTTP 资源 在服务器上 我们在该 API 的默认站点下有应用程序
  • IronPython:没有名为 json 的模块

    我安装了 IronPython 我的 python 文件如下所示 import sys print sys version import json 运行它的代码 var p Python CreateEngine var scope p C
  • 当前的 c++ 工作草案与当前标准有何不同

    通过搜索该标准的 PDF 版本 我最终找到了这个链接C 标准措辞草案 http www open std org jtc1 sc22 wg21 docs papers 2012 n3376 pdf从 2011 年开始 我意识到我可以购买最终
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • C 语言中 =+(等于加)是什么意思?

    我碰到 与标准相反 今天在一些 C 代码中 我不太确定这里发生了什么 我在文档中也找不到它 In ancientC 版本 相当于 它的残余物与最早的恐龙骨头一起被发现 例如 B 引入了广义赋值运算符 使用x y to add y to x
  • 将数据打印到文件

    我已经超载了 lt lt 运算符 使其写入文件并写入控制台 我已经为同一个函数创建了 8 个线程 并且我想输出 hello hi 如果我在无限循环中运行这个线程例程 文件中的o p是 hello hi hello hi hello hi e
  • 将构建日期放入“关于”框中

    我有一个带有 关于 框的 C WinForms 应用程序 我使用以下方法将版本号放入 关于 框中 FileVersionInfo GetVersionInfo Assembly GetExecutingAssembly Location F
  • 当“int”处于最大值并使用 postfix ++ 进行测试时,代码定义良好吗?

    示例 未定义行为的一个示例是整数溢出的行为 C11dr 3 4 3 3 int溢出是未定义的行为 但这是否适用于存在循环的以下内容 并且不使用现在超出范围的副作用i 特别是 这是否后缀增量规格帮助 结果的值计算在副作用之前排序 更新操作数的
  • 当我“绘制”线条时,如何将点平均分配到 LineRenderer 的宽度曲线?

    我正在使用线条渲染器创建一个 绘图 应用程序 现在我尝试使用线条渲染器上的宽度曲线启用笔压 问题在于 AnimationCurve 的 时间 值 水平轴 从 0 标准化为 1 因此我不能在每次添加位置时都在其末尾添加一个值 除非有一个我不知
  • 结构体指针的动态数组

    我必须使用以下代码块来完成学校作业 严格不进行任何修改 typedef struct char firstName char lastName int id float mark pStudentRecord pStudentRecord
  • 运算符“==”不能应用于“int”和“string”类型的操作数

    我正在编写一个程序 我想到了一个数字 然后计算机猜测了它 我一边尝试一边测试它 但我不断收到不应该出现的错误 错误是主题标题 我使用 Int Parse 来转换我的字符串 但我不知道为什么会收到错误 我知道它说 不能与整数一起使用 但我在网
  • 双精度类型二维多维数组的 pinvoke 编组作为 c# 和 c++ 之间的输入和输出

    我有以下我正在尝试解决的双物质类型的 2d 多维数组的 c 和 c pinvoke 编组 我已经查看了以下热门内容以获得我目前拥有的内容使用双精度数组进行 P Invoke 在 C 和 C 之间编组数据 https stackoverflo
  • 错误:无效使用不完整类型“类 Move”/未定义对 Move::NONE 的引用

    拜托 我不知道为什么这个简单的代码被拒绝 它给了我 2 个编译错误 请帮帮我 I use 代码 块 20 03 我的编译器是GNU GCC 移动 hpp class Move public Move Move int int public

随机推荐

  • bcrypt 不是 azure 应用服务上的有效 win 32 应用程序

    为了使用 Node 库 Sharp 进行一些图像处理 我必须将 Azure 应用服务上的节点可执行文件升级到 64 位 我通过手动下载可执行文件然后将其路径设置为IISNode yml 不幸的是 当我启动应用程序时 它会抛出以下错误 应用程
  • 将 .obj 转换为 .js 文件

    我已经浏览了不同的 Three js 示例 某些示例使用 js 或 bin 文件而不是 obj 文件 例如用于 webgl materials cars html 示例 如何获取 obj 文件的 js 文件 The 三 js编辑器 转换器
  • 将 jquery 函数应用于 ajax 内容

    我想将此功能应用于由ajax加载的内容 问题是 该功能不适用于此类内容 这个每个功能有某种解决方法吗 liquidcam each function index if this width this height this parent p
  • 跳跃扭曲的光标

    我正在尝试使用 Objective C 沿着任何 UI 元素外部的路径移动 Mac 光标的位置 不仅仅是在某些窗口上 而是在整个屏幕上 与鼠标悬停的位置无关 我不想直接将鼠标扭曲到某个位置 而是逐步将其移动到那里 即迭代循环 并在每次迭代中
  • gets.chomp 而不移动到新行

    我了解自动在末尾的 nputs and gets 以及如何处理这些问题 但是有没有办法在按 Enter 进行输入后保持显示点 光标位置 如果愿意的话 移动到新行gets e g print Hello my name is a gets c
  • 如何在Python中使用nosetest/unittest断言输出?

    我正在为下一个函数编写测试 def foo print hello world 所以当我想测试这个函数时 代码将是这样的 import sys from foomodule import foo def test foo foo outpu
  • Web 应用程序问题(web.config 错误) 使用 IIS7.5 和 ASP.NET v2 的 HTTP 500.19

    这让整个团队都快疯了 IIS 或我们的 Web 服务器肯定有一些简单的错误配置部分 但每次我们尝试在 IIS 7 5 上运行 ASP NET Web 应用程序时 我们都会收到以下错误 这是完整的错误 HTTP Error 500 19 In
  • .NET NetworkStream.EndWrite() 写入的字节数

    MSDN文档明确指出 获取到NetworkStream后 可以调用EndWrite方法 成功完成发送操作并返回数量 发送的字节数 强调我的 但是 它什么也不返回 void public override void EndWrite IAsy
  • PHP,一个奇怪的变量范围?

    这更多的是一个关于 为什么 然后 如何做 的问题 但它已经困扰我好几天了 目前 我正在使用 CodeIgniter 进行一些工作 并暂时从 Ruby 返回到 PHP 这让我对以下作用域魔法感到困扰
  • 使用可重用图表更新 d3.js 中的 HTML 表格

    我有这个可重复使用的模式来创建一张桌子 灵感来自http bl ocks org 3687826 我对此有两个问题 这是函数 d3 table function config var columns var tbl function sel
  • ggplotly 从单个方面删除数据

    我正在尝试为闪亮的应用程序创建一个绘图 我遇到了有关多面图的某些布局的问题 每当有四个小平面并且它们位于 2x2 网格中时 左下小平面不会显示任何数据 即使数据存在于ggplot数字 当 3x2 网格中有 6 个面且左下角再次被丢弃时 也会
  • 类型同义词与类型类约束是否可能?

    请随意更改标题 我只是经验不足 不知道到底发生了什么 所以 我正在松散地编写一个程序this 并写下了这个 与原文一样 type Row a a type Matrix a Row a 那里没什么特别的 然而 我发现自己编写了几个具有如下类
  • 在宏运行结束时打开 NUMLOCK

    什么代码的作用 我有一个代码可以在屏幕上移动鼠标 打印屏幕并将其粘贴到 Excel 中 Problem 由于某种原因 我的代码总是 绝对没有例外 在每次运行后关闭 NUMLOCK 键 到目前为止我尝试过的 我四处搜寻 发现了 SendKey
  • 查询为空 PHP 错误

    我正在尝试使用 MySQL 构建一个购物车 当我运行此代码时 我不断收到此错误 查询为空 请帮助我尝试了几种方法 例如将变量放入字符串中而不是连接它
  • HTML 链接不会转到外部网站

    我在构建网站时一直使用react js运行本地主机网站 当我尝试链接到外部网站 例如youtube 时 它最终会转到如下链接 http localhost 3000 www youtube com 当我试图去时 https www yout
  • 我可以立即打印循环中的每次迭代吗?

    我的部署服务器为每个新的数据库构建运行一个部署脚本 部分脚本会阻塞以等待另一个异步操作完成 阻塞代码如下所示 DECLARE i INT 0 DECLARE laststatus NVARCHAR MAX N WHILE i lt 5 BE
  • cusparse csrsv_analysis 的性能非常慢

    我编写了一个带有 LU 预处理的共轭梯度求解器 用于线性方程组 我使用了 Maxim Naumov 博士的papers以nvidia的研究社区为指导 残差更新步骤需要先求解下三角矩阵系统 然后求解上三角矩阵系统 分为两个阶段 分析阶段 利用
  • 选择工资高于其部门平均水平的每位员工

    我只有 1 个名为EMPLOYEE在我的数据库中包含以下 3 列 Employee Name Employee Salary Department ID 现在我必须选择每个工资高于其部门平均水平的员工 我怎么做 我遇到的主要问题是 当将每个
  • 错误:只能在初始化程序中访问静态成员,这是什么意思?

    我有这样的东西 我很难理解这个错误 为什么访问filterController这里给出这个错误 但是如果我移动当前的整个内容 它不会给出这个错误TextFormField在构建方法中创建 在注释 A 和 B 之间 整个搬家如何TextFor
  • 从 MVC 的 DependencyResolver 转换到 AutofacWebApiDependencyResolver - .Current 在哪里?

    我让 AutoFac 与 MVC4 一起正常工作 我正在尝试过渡到 Web API 2 以下是我设置 AutoFac 的方法 public class AutofacRegistrations public static void Regi