简体   繁体   English

服务定位器反模式可以用于工厂注册

[英]Service Locator Anti-Pattern Okay For Factory Registration

I'm creating a REST framework, and I'm wondering if it's okay to provide access to the service provider since it will be used in the Factory.我正在创建一个 REST 框架,我想知道是否可以提供对服务提供者的访问,因为它将在工厂中使用。 I have a generic service which has events that fire on Create and Update我有一个通用服务,它具有在创建和更新时触发的事件

public event Func<object, TDTO, Task> CreateEvent;

protected virtual async Task OnCreated(TDTO dto)
{
    await ServiceEventHandlerRule.OnServiceEvent(CreateEvent, this, dto);
}

public async Task<TDTO> Create(TDTO dto)
{
    var entity = this.DtoToEntity(dto, new TEntity());
    this._context.Set<TEntity>().Add(entity);

    dto = await this.SaveEntity(entity);
    await OnCreated(dto);
    return dto;
}

I'm registering Events on my sevices in a factory, Currently I'm exposing a Func<IServiceProvider, Object, TDto> Event Registration looks like so, this occurs in my startup.cs:我正在工厂的服务上注册事件,目前我公开了一个Func<IServiceProvider, Object, TDto>事件注册看起来像这样,这发生在我的 startup.cs 中:

var serviceConfig = new ServiceConfiuration<User, UserDTO>();
serviceConfig.EventMapping.AddCreateEvent(async (sp, obj, dto) => {
    var hubTaskQueue = sp.GetService<IHubServiceTaskQueue>();
    hubTaskQueue.QueueCreate<THub, TDTO>(dto);
});
services.AddScopedRestService(serviceConfig);

Users will need access to a few extra dependencies for their events so I've given them access to the IServiceProvider ,用户将需要访问其事件的一些额外依赖项,因此我已授予他们访问IServiceProvider权限,

What is the downside of using the Service Location Pattern During Registration?在注册期间使用服务位置模式有什么缺点?

Should I mask IServiceProvider and make a few Generic Overload which will auto resolve their dependencies?我应该屏蔽 IServiceProvider 并进行一些通用重载来自动解决它们的依赖关系吗?

In Dependency Injection Principles, Practices, and Patterns , we define Service Locator as:依赖注入原则、实践和模式中,我们将服务定位器定义为:

A Service Locator supplies application components outside the Composition Root with access to an unbounded set of Volatile Dependencies . Service LocatorComposition Root之外的应用程序组件提供对一组无限制的Volatile Dependencies 的访问 [Chapter 5.2] [第5.2章]

A Composition Root is a single, logical location in an application where modules are composed together.组合根是应用程序中将模块组合在一起的单个逻辑位置。 You can find a detailed description of what a Composition Root is in this excerpt from the book.您可以在本书的摘录中找到有关什么是组合根的详细说明。

In respect to your question, the important part of the Service Locator definition is: "outside the Composition Root".关于您的问题,服务定位器定义的重要部分是:“在组合根之外”。 In other words, accessing an unbounded set of Volatile Dependencies from within the Composition Root is fine, and is not an implementation of the Service Locator anti-pattern.换言之,由该组合物根访问无界集合挥发性依赖的是好的,并且不是服务定位器反模式的实现。 Accessing them outside the Composition Root, however, is an anti-pattern.然而,在组合根之外访问它们是一种反模式。

So to answer your question, you can safely let your factory depend on the container or an abstraction that resolves an unbounded set of dependencies, as long as your factory implementation is part of the Composition Root.因此,要回答您的问题,只要您的工厂实现是组合根的一部分,您就可以安全地让工厂依赖于容器或解决无限依赖集的抽象。

You can achieve this by placing the factory's abstraction close to your application logic, while you create a factory implementation in the start-up assembly of your application.您可以通过将工厂的抽象放在靠近应用程序逻辑的位置来实现这一点,同时在应用程序的启动程序集中创建工厂实现。

Users will need access to a few extra dependencies for their events so I've given them access to the IServiceProvider, What is the downside of using the Service Location Pattern During Registration?用户将需要访问其事件的一些额外依赖项,因此我已授予他们访问 IServiceProvider 的权限,在注册期间使用服务位置模式的缺点是什么?

If the code that depends on the IServiceProvider is not part of the Composition Root, they use the Service Locator anti-pattern, and this should be prevented.如果依赖于IServiceProvider的代码不是组合根的一部分,它们将使用服务定位器反模式,这应该被阻止。 Main problems with the Service Locator anti-pattern are:服务定位器反模式的主要问题是:

  • The module drags along the Service Locator as a redundant Dependency.该模块沿服务定位器拖动作为冗余依赖项。
  • The module makes it non-obvious what its Dependencies are.该模块使其依赖项是不明显的。 This makes such module harder to test, obscures the fact that a class might be too complex, and makes it harder to verify the correctness of the dependency graph, since dependencies are fetched lazily.这使得这样的模块更难测试,掩盖了一个类可能太复杂的事实,并使验证依赖图的正确性变得更加困难,因为依赖是惰性获取的。

Instead, you should let those users define their dependencies as constructor arguments.相反,您应该让这些用户将他们的依赖项定义为构造函数参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM