如何使用 WebAPI、WCF、SignalR 和后台任务在 MVC Web 应用程序中配置简单的注入器容器和生活方式

2024-01-11

简单的注入器文档提供了关于如何为 WebRequest、Web API、WCF 设置容器的很好的示例,但这些示例一次只针对一种技术/生活方式。我们的网络应用程序同时使用了它们中的大部分! 我不清楚如何配置容器以适应多种生活方式。


假设我有一个带有 Web API 的 MVC 项目。我有以下对象:

  • MyDbContext :我的实体代码第一个数据库上下文
  • IMyDataProvider 由 MyDataProvider 实现:包含查询逻辑并使用 MyDbContext
  • MyController :使用 IMyDataProvider 的 MVC 控制器
  • My ApiController :使用 IM DataProvider 的 Web Api 控制器

我应该为每种生活方式创建和配置一个容器吗?

当我注册所有内容时RegisterPerWebRequest<T>适用于两种类型的控制器。这样安全吗?或者在 Web API 控制器中使用 async/await 时我会遇到麻烦吗?

当我同时拥有注入相同实例的 MVC 和 Web API 控制器时,最佳配置是什么?

我应该采用混合生活方式吗?


现在事情变得复杂了......我们的应用程序还使用后台任务和 SignalR。

这两种情况有时都会发生在 WebRequest 之外,并且需要访问如上所述的相同对象。

最好的解决方案是使用 Lifetime 范围?

我需要为这种生活方式创建一个新的容器吗?或者我可以重用/重新配置我的 MVC/Web API 容器吗?

有没有三重生活方式?


我不得不说,不久前我偶然发现了类似的场景,我最终通过我的 Web API 和 signalR 共享了我的配置,但是您需要为 signalR 实现自定义生活方式,因为它不是基于 Web 请求。

特别是在 signalR 中,您会发现一些处理 Hub 中每个 Web 请求依赖项的问题,其中一些问题将为 null,例如 httpContext.Current 等。

解决方案:

您需要 WebRequestLifestlye 和 Lifestyle.Transient、Lifestyle.Singleton 或 LifetimeScopeLifestyle 之间的混合生活方式。我最终完成了装饰器模式的使用,你可以阅读这个post https://cuttingedge.it/blogs/steven/pivot/entry.php?id=91还有这个post https://cuttingedge.it/blogs/steven/pivot/entry.php?id=92.

我的装饰师

public class CommandLifetimeScopeDecorator<T> : ICommandHandler<T>
    {
        private readonly Func<ICommandHandler<T>> _handlerFactory;
        private readonly Container _container;

        public CommandLifetimeScopeDecorator(
        Func<ICommandHandler<T>> handlerFactory, Container container)
        {
            _handlerFactory = handlerFactory;
            _container = container;
        }

        public void Handle(T command)
        {
            using (_container.BeginLifetimeScope())
            {
                var handler = _handlerFactory(); // resolve scoped dependencies
                handler.Handle(command);
            }
        }

    }

    public interface ICommandHandler<in T>
    {
        void Handle(T command);
    }

我使用 signalR 的集线器激活器管理依赖项

public class MyHubActivator : IHubActivator
    {
        private readonly Container _container;

        public MyHubActivator(Container container)
        {
            _container = container;
        }

        public IHub Create(HubDescriptor descriptor)
        {
            return _container.GetInstance(descriptor.HubType) as IHub;
        }
    }

一个复合根文件,您将在其中处理依赖项

public CompositRoot(Container container)
{
    _container = container;
}
public container Configure()
{
   // _container.Registerall container dependencies
   return _container;
}

然后在引导应用程序时共享您的复合根配置

var compositRoot = new CompositRoot(simpleInjector.Container); //simple injector instance
compositRoot.Configure();

对于信号R

GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => new MyHubActivator(compositRoot));

并且您可以在其他项目中重复使用您的配置!

我的两分钱 希望有帮助!

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

如何使用 WebAPI、WCF、SignalR 和后台任务在 MVC Web 应用程序中配置简单的注入器容器和生活方式 的相关文章

  • 获取 TextBox 中的文本行数

    我试图通过标签显示文本框中的文本行数 但是 问题是如果最后一行为空 标签必须显示没有空行的行号 例如 如果它们有 5 行 最后一行为空 则标签应将行数显示为 4 Thanks private void txt CurrentVinFilte
  • 成员字段、构建顺序

    在 C 中 当执行如下所示的操作时 构造顺序是否得到保证 Logger Logger kFilePath logs runtime log logFile kFilePath 是的 施工顺序始终得到保证 但是 不能保证它与对象在初始值设定项
  • 如何向WebRequest添加参数?

    我需要从 Web 服务调用一个方法 所以我编写了以下代码 private string urlPath http xxx xxx xxx manager string request urlPath index php org get or
  • 显示 div 内的用户名列表

    我是 jQuery 新手 在我的项目中 我创建了一个类User其中代码如下所示 static ConcurrentDictionary
  • JetBrains Rider 针对 4.5 框架,无法切换到 4.7

    基本上 当尝试添加不支持旧框架的 NuGet 包时 会出现错误 但是在项目配置中只有 4 5 可用 在项目创建过程中 不存在选择目标的选项 有什么方法可以正确配置它吗 I haven t found out how to set up NE
  • std::bind2nd 和 std::bind 与二维数组和结构数组

    我知道 C 有 lambda 并且 std bind1st std bind2nd 和 std bind 已弃用 然而 从C 的基础开始 我们可以更好地理解新特性 所以 我从这个非常简单的代码开始 使用int 数组s 第一个例子 与std
  • 如何将 Visual-Studio 2010 切换到 c++11

    我是 c 编程新手 我想尝试 c 11 新功能 那么我要问的是如何切换 Visual studio 2010 才能编译 c 11 源代码 你可以参考这个表 VC10 中的 C 0x 核心语言功能 表格 http blogs msdn com
  • 为什么我在 WinForms 列表框中得到“System.Data.DataRowView”而不是实际值?

    每当我运行代码并尝试查看highscore我在列表框中得到的只是System Data DataRowView 谁能明白为什么吗 Code MySqlConnection myConn new MySqlConnection connStr
  • += 运算符在 C++ 中是如何实现的?

    这是我一直在思考的一个问题 但从未找到任何资源来说明这个问题的答案 事实上它不仅是为了 也适用于它的兄弟姐妹 即 等等 当然不是 考虑这个例子 int a 5 a 4 this will make a 9 现在考虑等效表达式 a a 4 T
  • 原子的 C++ 内存屏障

    在这方面我是个新手 谁能提供以下内存屏障之间差异的简化解释 窗户MemoryBarrier 围栏 mm mfence 内联汇编asm volatile memory 内在的 ReadWriteBarrier 如果没有简单的解释 一些好文章或
  • 如何在 ASP.NET Core 项目中使用 MStest 测试 Ok() 结果

    我正在使用 MStest 来测试我的控制器 我想测试这个动作 HttpGet Name GetGroups public async Task
  • 文本框中“结束编辑”的事件

    我正在 winform c 中使用文本框 并使用文本在数据库中进行查询 但每次文本更改时 我都需要不断查阅文本框的文本 因此 对于这些 我使用 KeyUp 但这个活动太慢了 文本框编辑完成后是否会触发任何事件 我考虑完成2个条件 控制失去焦
  • 如何使 WinForms UserControl 填充其容器的大小

    我正在尝试创建一个多布局主屏幕应用程序 我在顶部有一些按钮链接到应用程序的主要部分 例如模型中每个实体的管理窗口 单击这些按钮中的任何一个都会在面板中显示关联的用户控件 面板包含用户控件 而用户控件又包含用户界面 WinForms User
  • 在 lua 中加载 C++ 模块时出现“尝试索引字符串值”错误

    我正在尝试使用 lua 用 C 编写的函数 下面给出的是cpp文件 extern C include lua h include lauxlib h include lualib h static int add 5 lua State L
  • 使用方法的状态模式

    我正在尝试使用方法作为状态而不是类来基于状态模式的修改版本来实现一个简单的状态机 如下所示 private Action
  • 包含从代码隐藏 (ASP.NET C#) 到 ASPX 中的图像概述的图像列表 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何创建实体集或模型而不在数据库中创建相应的表 - 实体框架

    我的 sqlserver 数据库中有一个存储过程 它返回多个结果集 我正在使用 msdn 中的以下链接从实体框架中的 SP 读取多个结果集 https msdn microsoft com en us library jj691402 v
  • 有没有办法在 C# 中仅通过文件名查找文件?

    我们现在使用绝对路径或相对路径在 C 应用程序中查找文件 如果文件位于当前工作目录下或 路径 之一下 有没有办法仅通过名称查找文件 使用绝对路径不好 使用相对路径也不够好 因为我们可能通过重命名或移动项目文件夹来更改项目结构 如果我们的代码
  • 线程安全的有限大小队列,不使用锁

    我正在尝试编写一个主题队列 但遇到死锁和其他多线程问题 我想用Interlocked CompareExchange避免lock用法 但这段代码并没有按预期工作 它只是擦除整个队列 我在这里做错了什么 public class FixedS
  • 查找和替换正则表达式问题

    感谢这里对我其他问题的所有大力帮助 我开始掌握正则表达式 但我仍然对这个一无所知 我的代码是 StreamReader reader new StreamReader fDialog FileName ToString string con

随机推荐