- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在 ASP.NET MVC 项目中使用简单注入(inject)器。我添加了 SimpleInjector.Integration.Web.Mvc
nuget 包。这会在 App_Start
文件夹中添加 SimpleInjectorInitializer
类并初始化 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 Controller 正确配置了 DI。
我的问题是,如果我想在任何 Controller \类中获取容器实例以手动解决某些依赖项,我该怎么做。
我之前曾在 AutoFac 上工作过,它有一个依赖接口(interface) IComponentContext
,可以将其注入(inject)到任何需要手动执行任何解析的类中。
更新:
这是一个场景。我的 Controller 使用的服务初始化取决于 Controller 方法中传递的输入参数,因此在构建期间无法实例化依赖项。
我知道这在某种程度上是 DI 的反模式,但它在少数地方是必需的,因此注入(inject) DI 容器是下一个最佳选择。 Simple Injector 示例应该使用静态变量来共享我想避免的容器,而且 SimpleInjectorInitializer
的工作方式也不可能。
最佳答案
除了作为应用程序启动路径一部分的任何代码外,任何代码都不应直接依赖于容器(或容器抽象、容器外观等)。此模式称为 Service Locator和 Mark Seemann有一个good explanation为什么这是个坏主意。
因此组件(例如 Controller )不应直接依赖于容器,因为这会隐藏使用的依赖项并使类更难测试。此外,您的代码开始依赖于外部框架(使其更难更改)或依赖于它不需要了解的抽象。
My controller uses a service who initialization depends upon the input parameter passed in the controller method and hence the dependency cannot be instantiated during construction time
这个问题有一个通用模式:abstract factory design pattern .工厂模式允许您延迟类型的创建,并允许您为特定类型的构造传入额外的运行时参数。当您执行此操作时,您的 Controller 不必依赖于 Container,并且它可以防止您必须在单元测试中传入构造的容器(DI 框架通常不应在您的单元测试项目中使用)。
但是请注意,让您的组件需要 runtime data during creation is a code smell .防止这样做。
您可能认为这样做只是将问题转移到工厂实现中。虽然我们将对容器的依赖转移到工厂实现中,但实际上我们正在解决问题,因为工厂实现将成为应用程序的 Composition Root 的一部分。 ,它允许应用程序代码本身不受任何 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)
)所以你总是可以将容器注入(inject)任何组件。这类似于注入(inject) IComponentContext
使用 Autofac 时。但同样适用于 Autofac、Simple Injector 和任何其他容器:您不想将您的容器注入(inject)到位于组合根之外的组件中(而且几乎没有理由这样做)。
关于c# - 获取 Simple Injector 的容器实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17906423/
$injector.instantiate有什么区别, $injector.get和 $injector.invoke在 AngularJS 中? 最佳答案 鉴于以下服务: app.service('
我尝试使用两种方式显式创建依赖关系。两者几乎相同,但我有点困惑使用反射注入(inject)器比普通注入(inject)器有什么优势,推荐使用哪种方式? 使用注入(inject)器 import { I
我对 Angular js 很陌生,以下是我的代码 (function(angular){ var testAngular = angular.mo
在英雄之旅教程的第 5 节中,main.dart 包含以下行: final InjectorFactory injector = self.injector$Injector; 这是错字吗?它在 VS
你好我是 Angular JS 的初学者,当我开始创建模块和 Controller 时,我无法打印我的消息,下面是我的代码 var myModule = angular.module("myFirst
我只是想在 Angular Dart 中尝试路由。我在关注这个https://webdev.dartlang.org/angular/guide/router/1指导,但我收到错误。 这一行给出错误
自从我设置一个与 Angular 一起运行的网络应用程序以来已经有一段时间了。我正在通过一个旧项目回顾我的步骤(尝试在我正在做的页面上实现一个 Controller ,确保 Controller 文件
我正在尝试学习 Angular,但无法正确加载它。我看了一下关于 SO 的类似问题,但找不到我要找的东西。 有人知道为什么会出现这个错误吗?在我看来,我是否正确地调用了我的新应用程序/模块?我的剧本错
我使用环回作为后端,使用 postgresql 作为数据库。所以我尝试使用 lb-service/js。 如果我尝试在 login.js 中包含 lbServices (angular.module(
我正在尝试将表情符号应用程序注入(inject)我的项目。 我添加了emoji.min.js并像这样引用它 现在我也将它注入(inject)到我的项目中,如下所示: angular.module('
当我尝试将 $cookie 包含到我的 Controller 中时出现此错误。 任何人都可以向我解释我做错了什么? 我在 index.html 中有 angular-cookie.js 我在 conf
我正在使用 anguarjs 开发一个应用程序,并出现如下错误: 无法实例化模块 myApp,原因是:错误:[$injector:modulerr] http://errors.angularjs.o
var demoapp = angular.module('demoapp', []); demoapp.controller('SimpleC
我正在尝试通过网络摄像头简单地读取二维码,但我在控制台打开 Angular 帮助页面时遇到此错误,但说使用 ngRoute Error: [$injector:modulerr] http://err
我正在尝试对此进行编码,只是使用路由从第一个页面跳转到另一个页面,但为什么它不起作用,我搜索并使用了很多技巧但仍然失败,请问有人吗? index.html Angular Js
我收到此错误: ncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to: Error: [$inje
我正在尝试创建一个带有 Angular 路由的 SPA(单页应用程序),但是当我将 ndRoute 添加到我的模块时,它给了我这个错误 Uncaught Error: [$injector:modul
this is the error i m getting.这个问题被问了很多次。但是下面的代码在在线编译器中运行良好,但在我的本地系统中运行不佳,即使系统已连接到互联网,它也显示未定义 Angula
我正在尝试学习 Angular 并尝试在基于 Web 的教程之外编写我的第一个 Controller 。我一直在 JS 控制台的标题中收到错误消息,无法弄清楚发生了什么。该链接将我带到一个引用需要包含
我在尝试编写代码时遇到此错误。我已经完成了其他 Stackflow 问题,但找不到答案。是什么导致了这个错误? var app = angular.module("app", ['ui.router'
我是一名优秀的程序员,十分优秀!