Questions tagged «dependency-injection»

通过动态地将其需要起作用的依赖项注入软件组件来减少组件之间的耦合的设计模式。

11
具有文件系统依赖性的单元测试代码
我正在编写一个组件,给定一个ZIP文件,该组件需要: 解压缩文件。 在解压缩的文件中找到一个特定的dll。 通过反射加载该dll并在其上调用方法。 我想对该组件进行单元测试。 我很想编写直接处理文件系统的代码: void DoIt() { Zip.Unzip(theZipFile, "C:\\foo\\Unzipped"); System.IO.File myDll = File.Open("C:\\foo\\Unzipped\\SuperSecret.bar"); myDll.InvokeSomeSpecialMethod(); } 但是人们经常说:“不要编写依赖于文件系统,数据库,网络等的单元测试。” 如果我以对单元测试友好的方式编写此代码,我想它看起来应该像这样: void DoIt(IZipper zipper, IFileSystem fileSystem, IDllRunner runner) { string path = zipper.Unzip(theZipFile); IFakeFile file = fileSystem.Open(path); runner.Run(file); } 好极了!现在可以测试了;我可以将测试双打(模拟)输入DoIt方法。但是要花多少钱呢?我现在必须定义3个新接口才能使其可测试。我到底在测试什么?我正在测试我的DoIt函数与其依赖项正确交互。它无法测试zip文件是否已正确解压缩,等等。 感觉好像我不再在测试功能。感觉就像我只是在测试课堂互动。 我的问题是:对依赖于文件系统的内容进行单元测试的正确方法是什么? 编辑我正在使用.NET,但是该概念也可以应用Java或本机代码。

7
ServiceLocator是反模式吗?
最近,我阅读了Mark Seemann的有关Service Locator反模式的文章。 作者指出了ServiceLocator是反模式的两个主要原因: API使用问题(我非常满意) 当类使用Service定位器时,很难看到其依赖关系,因为在大多数情况下,类只有一个PARAMETERLESS构造函数。与ServiceLocator相比,DI方法通过构造函数的参数显式公开依赖项,因此在IntelliSense中很容易看到依赖项。 维护问题(使我感到困惑) 请考虑以下示例 我们有一个使用服务定位器方法的“ MyType”类: public class MyType { public void MyMethod() { var dep1 = Locator.Resolve<IDep1>(); dep1.DoSomething(); } } 现在我们要向类“ MyType”添加另一个依赖项 public class MyType { public void MyMethod() { var dep1 = Locator.Resolve<IDep1>(); dep1.DoSomething(); // new dependency var dep2 = Locator.Resolve<IDep2>(); dep2.DoSomething(); } } …

2
InvalidOperationException:无法解析类型为“ Microsoft.AspNetCore.Http.IHttpContextAccessor”的服务
我开始将asp.net核心RC1项目转换为RC2,并遇到了目前IHttpContextAccessor无法解决的问题。 为了简单起见,我使用Visual Studio Template创建了新的ASP.NET RC2项目ASP.NET Core Web Application (.Net Framework)。比我为HomeController添加了为我创建的模板的构造函数。 public HomeController(IHttpContextAccessor accessor) { } 在启动应用程序后,我收到下一个错误: InvalidOperationException:尝试激活“ TestNewCore.Controllers.HomeController”时,无法解析类型为“ Microsoft.AspNetCore.Http.IHttpContextAccessor”的服务。Microsoft.Extensions.Internal.ActivatorUtilities.GetService(IServiceProvider sp,Type type,Type requiredBy,Boolean isDefaultParameterRequired) 在我的实际应用程序中,我需要IHttpContextAccessor在自己的服务类中进行解析以获取_contextAccessor.HttpContext.Authentication和访问权限_contextAccessor.HttpContext.User。RC1中的Everething效果很好。那么,它怎么应该在RC2中呢?

4
场注入到底是什么?如何避免?
我在有关Spring MVC和Portlet的一些帖子中读到,不建议使用字段注入。据我了解,字段注入是当您使用以下方式注入Bean时@Autowired: @Component public class MyComponent { @Autowired private Cart cart; } 在研究期间,我还阅读了有关构造函数注入的信息: @Component public class MyComponent { private final Cart cart; @Autowired public MyComponent(Cart cart){ this.cart = cart; } } 这两种类型的注射都有哪些优缺点? 编辑1:由于此问题被标记为该问题的重复,我检查了它。因为在问题和答案中都没有任何代码示例,所以我不确定我所使用的注入类型是否正确。


4
如何在Spring中将依赖项注入到自实例对象中?
假设我们有一个课程: public class MyClass { @Autowired private AnotherBean anotherBean; } 然后,我们创建了此类的对象(或者其他一些框架也创建了此类的实例)。 MyClass obj = new MyClass(); 是否仍然可以注入依赖项?就像是: applicationContext.injectDependencies(obj); (我认为Google Guice有这样的内容)

4
带有@Value的Spring表达式语言(SpEL):美元与哈希($与#)
与何时使用${...}相比,我有些困惑#{...}。Spring的文档仅使用#{...},但是有许多使用示例${...}。此外,当我开始使用SpEL时,我被告知要使用${...}它,并且效果很好。 对于那些感到困惑的人,我将以一个如何使用它的例子为例。 @Component public class ProxyConfiguration { @Value("${proxy.host}") private String host; @Value("${proxy.port}") private String port; : } 和一些属性文件: proxy.host=myproxy.host proxy.port=8000 我的问题是: 有什么区别或相同? 一个版本已弃用,所以我应该使用另一个版本吗?

4
Ioc / DI-为什么我必须引用应用程序入口点中的所有层/程序集?
(与此问题相关的EF4:为什么在启用延迟加载后必须启用代理创建?)。 我是DI的新手,所以请多多包涵。我知道容器负责实例化我所有的注册类型,但要这样做,它需要引用我的解决方案中的所有DLL及其引用。 如果我不使用DI容器,则不必引用我的MVC3应用程序中的EntityFramework库,而只需引用我的DAL / Repo层的业务层即可。 我知道最终所有DLL都包含在bin文件夹中,但是我的问题是必须能够通过VS中的“添加引用”显式引用它,以便能够发布包含所有必要文件的WAP。

3
ContextLoaderListener与否?
一个标准的Spring Web应用程序(由Roo或“ Spring MVC Project”模板创建)使用ContextLoaderListener和创建一个web.xml DispatcherServlet。为什么他们不仅使用DispatcherServlet并使其加载完整的配置? 我知道应该使用ContextLoaderListener来加载与Web不相关的内容,而DispatcherServlet用于加载与Web相关的内容(控制器等)。这样就产生了两个上下文:父上下文和子上下文。 背景: 我用这种标准方式做了几年了。 <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value> </context-param> <!-- Creates the Spring Container shared by all Servlets and Filters --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Handles Spring requests --> <servlet> <servlet-name>roo</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/spring/webmvc-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> 这通常会导致两个上下文及其之间的依存关系出现问题。过去,我总是能够找到解决方案,并且我强烈感觉这使软件结构/体系结构总是更好。但是现在我面对两种情况的问题。 -但是,这让我重新考虑了这两种上下文模式,我在问自己:我为什么要陷入这种麻烦,为什么不将所有spring配置文件都加载其中一个DispatcherServlet并ContextLoaderListener完全删除。(我仍将拥有不同的配置文件,但只有一个上下文。) 有什么理由不删除ContextLoaderListener吗?

4
javax.inject.Named注释应该用于什么?
我试图了解该javax.inject软件包,但不清楚javax.inject.Named应将注释用于什么目的。Javadoc没有解释其背后的想法。 Javadoc位于http://download.oracle.com/javaee/6/api/javax/inject/Named.html 我正在使用Spring 3.0编写一些示例程序,通过放在@Named一个bean上似乎将其添加到bean工厂中,但是Javadoc的描述是如此之轻,我无法分辨这是标准行为还是特定于Spring的行为。 我的问题是: @Named和之间有什么区别@Qualifier 您应该如何告诉Runtime系统某个类在其他类中应该是可注入的,它的注释是什么?相当于@Component春天? 更新1中有一个很好的解释,@Named并且@Qualifier在Nice文章中有关@Named和@Qualifier https://dzone.com/articles/java-ee6-cdi-named-components的文章很好,感谢@xmedeko将其链接到下面的评论。


8
Jersey 2.0的依赖注入
从没有任何Jersey 1.x知识的白手起家,我很难理解如何在Jersey 2.0项目中设置依赖项注入。 我也知道HK2在Jersey 2.0中可用,但是我似乎找不到帮助Jersey 2.0集成的文档。 @ManagedBean @Path("myresource") public class MyResource { @Inject MyService myService; /** * Method handling HTTP GET requests. The returned object will be sent * to the client as "text/plain" media type. * * @return String that will be returned as a text/plain response. */ @GET …

4
.NET Core DI,将参数传递给构造函数的方法
具有以下服务构造函数 public class Service : IService { public Service(IOtherService service1, IAnotherOne service2, string arg) { } } 使用.NET Core IOC机制传递参数的选择有哪些 _serviceCollection.AddSingleton<IOtherService , OtherService>(); _serviceCollection.AddSingleton<IAnotherOne , AnotherOne>(); _serviceCollection.AddSingleton<IService>(x=>new Service( _serviceCollection.BuildServiceProvider().GetService<IOtherService>(), _serviceCollection.BuildServiceProvider().GetService<IAnotherOne >(), "" )); 还有其他办法吗?

16
依赖项注入容器的好处是什么?
我了解依赖注入本身的好处。让我们以Spring为例。我还了解其他Spring功能(如AOP,不同类型的助手等)的好处。我只是想知道XML配置的好处是什么,例如: <bean id="Mary" class="foo.bar.Female"> <property name="age" value="23"/> </bean> <bean id="John" class="foo.bar.Male"> <property name="girlfriend" ref="Mary"/> </bean> 与普通的旧Java代码相比,例如: Female mary = new Female(); mary.setAge(23); Male john = new Male(); john.setGirlfriend(mary); 它更容易调试,检查编译时间,并且仅懂Java的任何人都可以理解。那么,依赖注入框架的主要目的是什么?(或一段显示其优点的代码。) 更新: 如果 IService myService;// ... public void doSomething() { myService.fetchData(); } 如果存在多个,IoC框架如何猜测要注入的myService的哪种实现?如果给定接口只有一个实现,而我让IoC容器自动决定使用它,则在出现第二个实现后,它将被破坏。并且,如果有意仅使用一种可能的接口实现,则无需注入该接口。 看到IoC的一小部分配置显示出它的好处,这将真的很有趣。我已经使用Spring一段时间了,我无法提供这样的示例。而且我可以显示单行代码,这些代码演示了休眠,dwr和其他我使用的框架的好处。 更新2: 我意识到IoC配置可以更改而无需重新编译。真的是个好主意吗?我可以理解,当有人想更改数据库凭据而无需重新编译时-他可能不是开发人员。在您的实践中,除开发人员外,其他人多久更改一次IoC配置?我认为对于开发人员而言,无需重新编译该特定类,而无需更改配置。对于非开发人员,您可能希望使他的生活更轻松,并提供一些更简单的配置文件。 更新3: 接口之间的映射及其具体实现的外部配置 使它具有延展性有什么好处?您不必将所有代码都放在外部,但可以肯定地将代码放在ClassName.java.txt文件中,可以即时读取和手动进行编译-哇,您避免了重新编译。为什么要避免编译? 节省编码时间,因为您以声明方式而不是在过程代码中提供映射 我知道有时声明式方法可以节省时间。例如,我仅声明一次bean属性与DB列之间的映射,并且hibernate在加载,保存,构建基于HSQL的SQL等方式时使用此映射。这就是声明性方法的工作原理。在Spring的情况下(在我的示例中),声明具有更多的行,并且与相应的代码具有相同的表现力。如果有这样的声明比代码短的例子-我希望看到它。 控制反转的原理使单元测试变得容易,因为您可以用假的实例替换实际的实现(例如用内存中的实例替换SQL数据库) …

7
AngularJS缩小最佳实践
我正在阅读 http://www.alexrothenberg.com/2013/02/11/the-magic-behind-angularjs-dependency-injection.html,事实证明,如果您缩小JavaScript的大小,angularjs依赖项注入会出现问题,所以我我想知道是否 var MyController = function($scope, $http) { $http.get('https://api.github.com/repos/angular/angular.js/commits') .then(function(response) { $scope.commits = response.data }) } 你应该使用 var MyController = ['$scope', '$http', function($scope, $http) { $http.get('https://api.github.com/repos/angular/angular.js/commits') .then(function(response) { $scope.commits = response.data }) }] 总之,我认为第二个片段是针对angularjs的旧版本的,但是.... 我是否应该始终使用注入方式(第二种方式)?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.