什么时候使用TryAddSingleton或AddSingleton? [英] When to use TryAddSingleton or AddSingleton?

查看:913
本文介绍了什么时候使用TryAddSingleton或AddSingleton?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到在某些.net核心示例中,有TryAddSingleton调用,而在AddSingleton中有一些注册服务的调用.

I've noticed in some .net core examples there are calls to TryAddSingleton, and in some AddSingleton when registering services.

反编译器显示TryAdd(由TryAddSingleton调用) 如果尚未注册服务类型,则将指定的参数描述符"添加到集合"中.

Decompiler shows that TryAdd( called by TryAddSingleton) adds the specified param "descriptor" to the "collection" if the service type hasn't been already registered.

如果其他一些方法/库已经注册了相同的类,这是否意味着使用TryAddSingleton总是更安全?

Does it mean that it always safer to use TryAddSingleton, in case if some other method/library already registered the same class?

推荐答案

您已经注意到,TryAddSingletonAddSingleton之间的区别是AddSingleton总是将注册附加到集合中,而仅TryAddSingleton如果没有针对给定服务类型的注册,则执行此操作.

As you already noticed, the difference between TryAddSingleton and AddSingleton is that AddSingleton always appends the registration to the collection, while TryAddSingleton only does this when there exists no registration for the given service type.

当同一服务类型存在多个注册,但请求一个实例时,.NET Core将始终返回最后一个.这意味着AddSingleton的行为是替换非集合解析的实例.例如:

When multiple registrations exist for the same service type, but one instance is requested, .NET Core will always return the last one. This means that the behavior of AddSingleton is to replace instances for non-collection resolves. For instance:

services.AddSingleton<IX, A>();
services.AddSingleton<IX, B>(); // ‘replaces’ A
IX x = container.GetService<IX>(); // resolves B

对于集合解析,AddSingleton的行为完全不同,因为在这种情况下,AddSingleton表现为该服务类型已经存在的注册的集合追加".例如:

For collection resolves however, AddSingleton behaves completely different, because in that case AddSingleton behaves as a collection ‘append’ of already existing registrations for that service type. For instance:

services.AddSingleton<IX, A>();
services.AddSingleton<IX, B>();
IEnumerable<IX> xs = container.GetServices<IX>(); // resolves A and B

对于TryAddSingleton,如果已经存在针对给定服务类型的注册,则不会添加注册.这意味着,与将服务类型解析为一个实例或实例集合的时间无关,当至少有一个注册时,将不会添加注册.例如:

With TryAddSingleton however, the registration will not be added when there already exist registrations for the given service type. This means that, independently of when a service type is resolved as one instance or as a collection of instances, the registration will not be added when there is at least one registration. For instance:

services.TryAddSingleton<IX, A>(); // adds A
services.TryAddSingleton<IX, B>(); // does not add B, because of A
IX x = container.GetService<IX>(); // resolves A

services.TryAddSingleton <IX, A>(); // adds A
services.TryAddSingleton <IX, B>(); // does not add B, because of A
IEnumerable<IX> xs = container.GetServices<IX>(); // resolves A

TryAddSingleton对于希望将其自己的组件注册到容器的框架和第三方库代码特别有用.即使应用程序开发人员在调用框架或第三方AddXXX扩展方法之前注册了该组件,它也允许应用程序开发人员覆盖框架或库的默认注册.例如:

TryAddSingleton is especially useful for framework and third-party library code that wishes to register its own components to the container. It allows an application developer to override the framework or library’s default registration, even if the application developer registered that component before the framework or third-party AddXXX extension method is called. For instance:

services.TryAddSingleton<IX, A>(); // adds A
services.AddThirdPartyLibrary (); // calls services.TryAddSingleton <IX, B>();
IX x = container.GetService<IX>(); // resolves A

如果第三方库调用了AddSingleton而不是TryAddSingleton,则应用程序开发人员的A将始终被覆盖,这可能会使开发人员感到困惑. 作为应用程序开发人员,您通常会知道自己注册了什么,这使得TryAddSingleton的使用对应用程序开发人员没有太大用处.

Would the third-party library have called AddSingleton instead of TryAddSingleton, the application developer’s A will always be overridden, which can be confusing for the developer. As an application developer, you typically know what you registered, which makes the use of TryAddSingleton not that useful for an application developer.

我什至会争辩说,从应用程序开发人员的角度来看,AddSingleton的行为可能非常棘手,因为它隐式地覆盖了现有注册,而没有任何警告.我的经验是,此行为可能导致难以发现配置错误.更安全的设计应该是具有AddSingletonAppendSingletonReplaceSingleton方法,其中AddSingleton将在存在注册的情况下引发异常,而ReplaceSingleton实际上将丢弃现有的注册.

I would even argue that, from perspective of an application developer, the behavior of AddSingleton can be very tricky, because it implicitly overrides an existing registration, without any warning whatsoever. My experience is that this behavior can cause hard to spot configuration errors. A safer design would have been to have AddSingleton, AppendSingleton and ReplaceSingleton methods, where AddSingleton would throw an exception in case a registration exists, and ReplaceSingleton would actually throw away the existing registration.

这篇关于什么时候使用TryAddSingleton或AddSingleton?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆