获取简单注入器的容器实例

2024-01-21

我正在 ASP.NET MVC 项目中使用简单注入器。我添加了SimpleInjector.Integration.Web.Mvcnuget 包。这增加了SimpleInjectorInitializer上课于App_Start文件夹并初始化 DI。代码看起来像

public static void Initialize()
{
    // Did you know the container can diagnose your configuration? 
    // Go to: https://simpleinjector.org/diagnostics
    var container = new Container();

    //Container configuration code
    DependencyResolver.SetResolver(
        new SimpleInjectorDependencyResolver(container));
}

这将正确配置 MVC 控制器的 DI。

我的问题是,如果我想获取任何控制器\类中的容器实例来手动解决某些依赖关系,我该怎么做。

我之前曾在 AutoFac 上工作过,它有一个依赖接口IComponentContext可以将其注入到任何需要手动执行任何解析的类中。

Update:

这是一个场景。我的控制器使用一个服务,该服务的初始化取决于控制器方法中传递的输入参数,因此在构造期间无法实例化依赖项。

我知道这在某种程度上是 DI 的反模式,但它在少数地方是必需的,因此注入 DI 容器是下一个最好的事情。简单的注入器示例应该使用静态变量来共享我想避免的容器,顺便说一句,这是不可能的SimpleInjectorInitializer works.


除了属于应用程序启动路径一部分的任何代码之外,任何代码都不应直接依赖于容器(或容器抽象、容器外观等)。这种模式称为服务定位器 http://martinfowler.com/articles/injection.html and 马克·西曼 http://blog.ploeh.dk/ has a 很好的解释 http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/为什么这是一个坏主意。

因此,组件(例如控制器)不应直接依赖于容器,因为这会隐藏所使用的依赖项并使类更难以测试。此外,您的代码开始依赖于外部框架(使其更难以更改)或依赖于它不需要了解的抽象。

我的控制器使用一个服务,该服务的初始化取决于输入 控制器方法中传递的参数以及依赖关系 无法在构造期间实例化

这个问题有一个通用模式:抽象工厂设计模式 https://en.wikipedia.org/wiki/Abstract_factory_pattern。工厂模式允许您延迟类型的创建,并允许您传入额外的运行时参数来构造特定类型。当您这样做时,您的控制器不必依赖于 Container,并且它可以防止您必须在单元测试中传递构造的容器(DI 框架通常不应在单元测试项目中使用)。

但请注意,让您的组件需要创建期间的运行时数据是一种代码味道 https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=99。防止这样做。

您可能认为这样做只是将问题转移到工厂实现上。尽管我们将对容器的依赖转移到工厂实现中,但实际上我们正在解决问题,因为工厂实现将成为应用程序的一部分成分根 http://blog.ploeh.dk/2011/07/28/CompositionRoot/,它允许应用程序代码本身忽略任何 DI 框架。

所以这就是我建议您构建代码的方式:

// Definition of the factory in the UI or BL layer
public interface ISomeServiceFactory
{
    ISomeService Create(int inputParameter);
}

// Controller depending on that factory:
public class MyController : Controller
{
    private readonly ISomeServiceFactory factory;

    public MyController(ISomeServiceFactory factory)
    {
        this.factory = factory;
    }

    public ActionResult Index(int value)
    {
        // here we use that factory
        var service = this.factory.Create(value);
    }
}

在您的组合根(启动路径)中,我们定义工厂实现及其注册:

private class SomeServiceFactory : ISomeServiceFactory
{
    private readonly Container container;

    // Here we depend on Container, which is fine, since
    // we're inside the composition root. The rest of the
    // application knows nothing about a DI framework.
    public SomeServiceFactory(Container container)
    {
        this.container = container;
    }

    public ISomeService Create(int inputParameter)
    {
        // Do what ever we need to do here. For instance:
        if (inputParameter == 0)
            return this.container.GetInstance<Service1>();
        else
            return this.container.GetInstance<Service2>();
    }
}

public static void Initialize()
{
    var container = new Container();

    container.RegisterSingle<ISomeServiceFactory, SomeServiceFactory>();
}

创建后,Container注册自身(使用调用RegisterSingle<Container>(this))因此您始终可以将容器注入到任何组件中。这类似于注入IComponentContext使用 Autofac 时。但这同样适用于 Autofac、Simple Injector 和任何其他容器:您不希望将容器注入到位于组合根之外的组件中(而且几乎没有理由这么做)。

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

获取简单注入器的容器实例 的相关文章

  • CLR 2.0 与 4.0 性能比较?

    如果在 CLR 4 0 下运行 为 CLR 2 0 编译的 NET 程序会运行得更快吗 应用程序配置
  • 将 MVC 站点部署到 IIS 会导致找不到默认共享部分视图

    我有一个可以在本地 IIS 上完美运行的网站 我的所有页面都使用默认的共享部分视图 这称为预期 Layout cshtml 该视图放置在我的共享文件夹中 这可以在这里看到 正如我所期望的那样 这非常有效 不过 我现在发布了我的网站 然后 我
  • 如何使用 Castle Windsor 将对象注入到 WCF IErrorHandler 实现中?

    我正在使用 WCF 开发一组服务 该应用程序正在使用 Castle Windsor 进行依赖注入 我添加了一个IErrorHandler通过属性添加到服务的实现 到目前为止一切正常 这IErrorHandler对象 一个名为FaultHan
  • 从同一个类中的另一个构造函数调用构造函数

    我有一个带有两个构造函数的类 C 这是代码片段 public class FooBar public FooBar string s constructor 1 some functionality public FooBar int i
  • 查看 NuGet 包依赖关系层次结构

    有没有一种方法 文本或图形 来查看 NuGet 包之间的依赖关系层次结构 如果您使用的是新的 csproj 您可以在此处获取所有依赖项 在项目构建后 项目目录 obj project assets json
  • Visual Studio 在构建后显示假错误

    我使用的是 Visual Studio 2017 构建后 sln在调试模式下 我收到错误 但是 当我通过双击错误列表选项卡中的错误来访问错误时 错误会从页面中消失 并且错误数量也会减少 我不太确定这种行为以及为什么会发生这种情况 有超过 2
  • 使用可变参数包类型扩展的 C++ 函数调用者包装器

    我绑定了一些 API 并且绑定了一些函数签名 如下所示 static bool WrapperFunction JSContext cx unsigned argc JS Value vp 我尝试将对象和函数包装在 SpiderMonkey
  • 如何在编辑器模板中获取序列/数组索引?

    案件 我有一个使用 X 类编辑器模板显示的 X 类项目列表 问题 如何获取编辑器模板内部正在处理的项目的索引 我一直在使用这个 HtmlExtension 它只返回迭代所需的 id 它基本上是一个正则表达式ViewData Template
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 为什么可以通过ref参数修改readonly字段?

    考虑 class Foo private readonly string value public Foo Bar ref value private void Bar ref string value value hello world
  • IQueryable 单元或集成测试

    我有一个 Web api 并且公开了一个端点 如下所示 api 假期 name name 这是 Web api 的控制器 get 方法 public IQueryable
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 在mysql连接字符串中添加应用程序名称/程序名称[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我正在寻找一种解决方案 在连接字符串中添加应用程序名称或程序名称 以便它在 MySQL Workbench 中的 客户端连接 下可见 SQL
  • C++ int 前面加 0 会改变整个值

    我有一个非常奇怪的问题 如果我像这样声明一个 int int time 0110 然后将其显示到控制台返回的值为72 但是当我删除前面的 0 时int time 110 然后控制台显示110正如预期的那样 我想知道两件事 首先 为什么它在
  • String.Empty 与 "" [重复]

    这个问题在这里已经有答案了 可能的重复 String Empty 和 有什么区别 https stackoverflow com questions 151472 what is the difference between string
  • OpenGL:仅获取模板缓冲区而没有深度缓冲区?

    我想获取一个模板缓冲区 但如果可能的话 不要承受附加深度缓冲区的开销 因为我不会使用它 我发现的大多数资源表明 虽然模板缓冲区是可选的 例如 排除它以利于获得更高的深度缓冲区精度 但我还没有看到任何请求并成功获取仅 8 位模板缓冲区的代码
  • GCC 的“-Wl,option”和“-Xlinker option”语法之间有区别吗?

    我一直在查看一些配置文件 并且看到它们都被使用 尽管在不同的体系结构上 如果您在 Linux 机器上使用 GCC 将选项传递给链接器的两种语法之间有区别吗 据我所知 阅读 GCC 手册时 他们的解释几乎相同 From man gcc Xli
  • 为boost python编译的.so找不到模块

    我正在尝试将 C 代码包装到 python 中 只需一个类即可导出两个函数 我编译为map so 当我尝试时import map得到像噪音一样的错误 Traceback most recent call last File
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke
  • 灵气序列解析问题

    我在使用 Spirit Qi 2 4 编写解析器时遇到一些问题 我有一系列键值对以以下格式解析

随机推荐