问题标签 [service-locator]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
interface - 依赖注入 - 与数据传输对象 (DTO) 一起使用?
考虑下面的代码(已简化)。我有一个服务类,它返回一个特定 DTO 对象的列表,每个对象都实现自己的特定接口。在实际代码中,当我使用遗留代码时,这些是通过迭代数据集来填充的。
问题:
我们如何在不更新它们或使用服务定位器反模式的情况下创建/使用 DTO?在组合根中组合一个空的 DTO 对象并通过构造函数将其注入到 Service 类中没有多大意义,因为我实际上在填充列表时会将 DTO 用作各种临时变量。
在代码中,您可以看到我更新 DTO 的示例。但这并不比我一开始就让 DTO 不实现接口好多少。那么他们是否应该不实现接口,从而不将 DI 与 DTO 一起使用?
multithreading - 如何在 WCF 服务中使用服务定位器
我正在使用服务定位器来保存在 WCF 服务中使用的类的具体实例。我决定将它设为静态,而不是传递 ServiceLocator,这样我就可以从每个类中访问它。服务定位器在 WCF 服务启动时填充,根据某些参数,它可以填充不同的具体实现。
我的问题是,如果在另一个调用完成之前对 WCF 服务进行了调用,那么(我认为)ServiceLocator 将填充不正确的实现。
有什么方法可以使服务定位器对类可用,并且不会被不同的线程或对 WCF 服务的调用重新使用?
castle-windsor - 避免使用不是为 IOC 设计的遗留应用程序的服务定位器反模式
我经常读到IOC 中的服务定位器是一种反模式。
去年,我们在工作中的应用程序中引入了 IOC(特别是 Ninject)。该应用程序是遗留的,它非常大而且分散。有很多方法可以创建一个类或一个类链。有些是由 web 框架创建的(这是自定义的),有些是由 nHibernate 创建的。很多只是散落在奇怪的地方。
我们将如何处理不同的场景,而不是想出至少不是 ServiceLocatorish 的东西,并且最终不会在不同的地方使用不同的内核(单例、HttpRequest 和线程等范围很重要)。
编辑我将添加更多细节来说明是什么导致了我们目前的 SL 模式。
我们实际上不想要多个内核。我们只想要一个(实际上由于 SL,我们只有一个静态的)。这是我们的设置:
1) 我们在 7-8 个不同的项目/程序集中有 Ninject 模块。当我们的应用程序(webapp)启动时,模块通过程序集扫描收集并加载到内核中并放置在服务定位器中。所以这一切都是相当昂贵的。
2) 我们有一个定制的 UI 框架,构建起来很开心。想想大约 120 个选项卡式表单,每个表单都构建 1-10 个选项卡页作为其生命周期的一部分。SL 战略性地用于 5-6 个地方,这些地方涵盖了所有这些,或者作为纯分辨率,或者只进行属性的实例化后注入。
3) UI 下的任何内容都没有被那些顶级调用覆盖,如果这些类想要使用 IOC,他们需要提出自己的策略。有各种不同的小框架,每一个都是他们自己的小世界。
因此,从我所读到的内容中,理想的方法是在您需要访问 IOC 时注入内核......好吧,这一切都很好;我们确实将 SL 的使用降至最低。
但是我从哪里得到这个内核呢?我不想到处构建和注册一个新的。似乎我必须将它从静态上下文或工厂中取出,这样我才能确保我正在使用的内核保持与其他人正在使用的相同范围对象,同时也避免注册所有的费用模块。在那一点上,无论那个东西是什么看起来很像一个服务定位器,对吧?
还要记住,这个应用程序非常庞大且紧密耦合。我们没有奢侈地花几个月的时间来一次重构它。SL 似乎是我们在有时间的情况下慢慢地在 IOC 工作的好方法。
dependency-injection - 在 Windows 客户端 (WPF) 应用程序中进行依赖注入的正确方法
我习惯于 Web 应用程序中的 IoC/DI - 主要是 Ninject 和 MVC3。我的控制器是为我创建的,填充了所有的依赖项、子依赖项等。
但是,在胖客户端应用程序中情况有所不同。我必须创建自己的对象,或者我必须恢复到服务定位器风格的方法,在这种方法中我要求内核(可能通过一些接口,以允许可测试性)给我一个完整的对象与依赖关系。
但是,我已经看到有几个地方将 Service Locator 描述为反模式。
所以我的问题是 - 如果我想在我的胖客户端应用程序中从 Ninject 中受益,有没有更好/更合适的方法来获得这一切?
- 可测试性
- 适当的 DI / IoC
- 尽可能少的耦合
请注意,我在这里讨论的不仅仅是 MVVM 以及将视图模型放入视图中。这具体是由需要从内核提供存储库类型对象触发的,然后从该存储库中获取注入功能的实体(数据当然来自数据库,但它们还需要一些对象作为参数,具体取决于状态世界,Ninject 知道如何提供)。我可以在不将存储库和实体都留下无法测试的混乱的情况下以某种方式做到这一点吗?
如果有任何不清楚的地方,请告诉我。谢谢!
编辑 7 月 14 日
我确信提供的两个答案可能是正确的。然而,我身体的每一根纤维都在与这种变化作斗争;其中一些可能是由于缺乏知识造成的,但还有一个具体原因是我无法看到这种做事方式的优雅之处;
我在最初的问题中没有很好地解释这一点,但问题是我正在编写一个库,该库将被几个(最初是 4-5 个,以后可能更多)WPF 客户端应用程序使用。这些应用程序都在相同的域模型等上运行,因此将它们全部保存在一个库中是保持 DRY 的唯一方法。然而,这个系统的客户也有可能编写他们自己的客户——我希望他们有一个简单、干净的库可以与之交谈。我不想强迫他们在他们的 Composition Root 中使用 DI(在他的书中使用 Mark Seeman 之类的术语)——因为与他们刚刚更新 MyCrazySystemAdapter() 并使用它相比,这使事情变得非常复杂。
现在,MyCrazySystemAdapter(之所以选择这个名字是因为我知道人们在这里会不同意我的观点)需要由子组件组成,并使用 DI 组合在一起。MyCrazySystemAdapter 本身不需要注入。它是客户端与系统对话时需要使用的唯一接口。因此,客户应该高兴地获得其中之一,DI 就像幕后发生的魔术一样,并且该对象由许多不同的对象使用最佳实践和原则组成。
我确实意识到这将是一种有争议的做事方式。但是,我也知道将成为此 API 客户的人。如果他们发现他们需要学习和连接 DI 系统,并在他们的应用程序入口点(组合根)中提前创建他们的整个对象结构,而不是新建一个对象,他们会给我中指和直接弄乱数据库并以您难以想象的方式搞砸事情。
TL;DR:提供结构合理的 API 对客户来说太麻烦了。我的 API 需要交付他们可以使用的单个对象——使用 DI 和适当的实践在幕后构建。现实世界有时会胜过将所有东西倒过来以忠于模式和实践的愿望。
architecture - 我应该如何在我的应用程序中构建日志记录?
所以我对此做了很多研究,但没有找到任何答案,我说“是的,那个”。我希望博学多才的 StackOverflow 人群可以帮助我。
我在几个不同的场景中遇到了这个问题。假设我有一个 C# 应用程序,并且我想要记录一些重要的事情。
我感兴趣的是我从哪里得到logger
。
正如我所看到的,我有几个选择。
- 将其注入到构造函数中的 MyClass 中。
- 使用全球可用的服务定位器检索它。
- 使用方法装饰器和 AOP 为我完成日志记录。
这些似乎都不是很好的选择。#3 看起来是不可能的,因为我在我的业务逻辑中间记录,而不仅仅是简单地跟踪我的方法调用、输入参数和/或抛出的异常。#2,虽然看起来很简单,但单元测试真的很难。当然,我想对所有内容进行单元测试。#1,虽然它可以正常工作,但我所有的业务逻辑都被与业务对象本身无关的日志对象弄乱了。
任何替代想法或对上述选项之一的想法?非常感谢!
编辑:为了清楚起见,我已经知道如何进行 DI(我使用 Unity),并且我已经知道一个好的日志框架(我使用 log4net)。只是想知道如何以最智能的方式在整个应用程序中使用架构意义上的日志记录。
* 编辑 *
I marked Mark Seeman's answer as the solution. I went through my application and found that most of my logging calls were doing the same thing a decorator could do. Namely, log the entry to the method, any exceptions thrown, and exit return values.
Some cases I still needed to log directly inside a method. An example would be where I want to fail fast in a method which doesn't return anything but not throw an Exception. In those cases I have a singleton which holds a reference a LogProvider
which will in turn retrieve a named log instance. The code looks similar to this:
LogProviderFactory has a method SetProvider
which allows you to swap out the singleton. So in unit testing I can do:
The logging decorator uses the same LogProvider as the singleton (which it obtains through injection), so logging is unified throughout the system.
So really the end solution was mostly option #3, and a hybrid #2 (where it's the service locator pattern but the service is 'injected' into the locator).
AOP
As far as "aspect oriented programming" goes, I was a bit disappointed in the limitations of the language. Hoping AOP will be treated as a first-class citizen in future releases.
- I tried PostSharp but couldn't get it running on my machine correctly. Additionally it was a big restriction that you had to have PostSharp installed on your system to use it (as opposed to just calling a dll which comes with the solution or something similar).
- I used LinFu and was able to get it partially working. It blew up in a few instances however. The new 2.0 release is barely documented, so that was a hurdle.
- Interface interception with Unity however seems to work well out of the box. I got lucky that most things I wanted to log were in classes implementing interfaces.
c# - 如何避免服务定位器反模式?
我正在尝试从抽象基类中删除服务定位器,但我不确定用什么替换它。这是我所拥有的伪示例:
这样做的问题是派生类的实例化器不知道内核必须具有哪些绑定才能MySpecialResolver
避免引发异常。
这可能本质上是棘手的,因为我不知道从这里我必须解决哪些类型。派生类负责创建types
参数,但它们在任何地方都没有硬编码。(这些类型基于派生类的组合层次结构深处存在的属性。)
我试图用延迟加载委托来解决这个问题,但到目前为止我还没有想出一个干净的解决方案。
更新
这里确实有两个问题,一个是 IoC 容器被传递给控制器,充当服务定位器。这很容易删除——您可以使用各种技术将位置向上或向下移动调用堆栈。
第二个问题是困难的,当需求直到运行时才暴露时,如何确保控制器具有必要的服务。从一开始就应该很明显:你不能!您将始终依赖于服务定位器的状态或集合的内容。在这种特殊情况下,再多的摆弄都无法解决本文中描述的静态类型依赖关系的问题。我认为我最终要做的是将惰性数组传递给控制器构造函数,如果缺少所需的依赖项,则抛出异常。
gwt - GWT / RequestFactory:在检索给定的实体列表时,执行 n+1 个 SQL 调用
当我使用带有 ServiceLocator 和 Locator 构造的 RequestFactory 请求实体列表时,GWT 执行 n+1 个 SQL 调用。
.net - 如何在 MVC3 中使用 Ninject 将服务注入视图/视图模型?
我将 MVC3 与 Ninject 一起使用,我的控制器中的依赖关系已毫无问题地解决。我几乎没有像本地化、格式提供程序这样的服务,我希望将它们注入到视图模型或 Razor 视图中。现在我手动将它们注入到我的视图模型中,
- 我怎样才能自动化呢?
- 我可以向 Razor 视图注入一些服务吗?
- 如何在 MVC 中使用 Ninject 设置服务定位器?
对于其他人: 似乎 Service Locator 是个坏主意,因为 Ninjects Bootstrapper.Kernel 已过时,而 Service Locator 是一种反模式。看看这篇文章http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx
_
c# - 如何在 XML 配置中声明 Unity InjectionFactory
我正在将我们的 Unity 配置移动到 web.config 文件中。我坚持如何将以下代码配置迁移到 xml 格式:
以下是 XML 声明:
asp.net-mvc-3 - ASP.NET MVC 3 - 替换公共服务定位器时的依赖关系解析器问题
使用 Microsoft Unity 我注册了以下类型:
在 ASP.NET MVC 2 中,我可以执行以下操作:
但是在第 3 版中。我已经删除了所有出现的服务定位器,而是实现了新的依赖解析器。因此,我将上述内容更改为:
但是,这现在返回 null。
如果有帮助,这是我对 Dependency Resolver 的实现:
如果有人能告诉我我做错了什么,我将不胜感激。谢谢