gpt4 book ai didi

c# - 在简单注入(inject)器中注册为单例的具有两个接口(interface)的类的行为是什么

转载 作者:行者123 更新时间:2023-11-30 20:23:46 25 4
gpt4 key购买 nike

我有以下类(class):

public class UserService : IUserService, IObserver<User>

我已经注册了IUserService作为单例到 UserService .之后我注册了 IObserver这样:

container.RegisterManyForOpenGeneric(typeof(IObserver<>),
container.RegisterAll,
typeof(IObserver<>).Assembly);

所以现在如果我注入(inject) IEnumerable<IObservable>到我的复合模式,当我枚举时,我会得到与解析 IUserService 时相同的对象吗? ?

它似乎以这种方式工作(只有一个对象存在 UserService 存在)至少如果我解析 IEnumerable第一的。我无法在文档中找到它,但这是 Simple Injector 支持的功能还是可以随时更改的巧合?如果是,那么我想这种行为对于任何两个或更多接口(interface)都是相同的,不一定是开放通用的?

最佳答案

您看到的行为是设计使然,并在 container.RegisterCollection(Type, IEnumerable) method 的文档中进行了描述(v2.x 中的 RegisterAll):

Registers a collection of serviceTypes, whose instances will be resolved lazily each time the resolved collection of serviceType is enumerated. The underlying collection is a stream that will return individual instances based on their specific registered lifestyle, for each call to IEnumerator<T>.Current. The order in which the types appear in the collection is the exact same order that the items were registered, i.e the resolved collection is deterministic.

尽管 API 文档对此进行了说明,但我必须承认文档对此不是很清楚。有other places描述此行为的位置,但此信息有点深埋在文档中。

但基本上,API 旨在允许这样做:

container.Register<ILogger, DefaultLogger>(Lifestyle.Transient);
container.Register<SqlLogger>(Lifestyle.Scoped);
container.Register<FileLogger>(Lifestyle.Singleton);

container.RegisteCollection<ILogger>(new[] {
typeof(MailLogger),
typeof(SqlLogger),
typeof(FileLogger),
typeof(ILogger)
});

这个配置有一个集合ILogger实现,其中集合中的第一个元素 ( MailLogger ) 将是 transient 的(如果 LifestyleSelectionBehavior 未被覆盖),第二个 ( SqlLogger ) 将是 Per Request,第三个 ( FileLogger )将是一个单例,第四个元素将解析 DefaultLogger作为 transient 。

it's a coincidence that can be changed at any time?

不,这是有记录、测试和支持的。尽管我们将(在 definition 之前)在下一个主要版本中引入重大更改,但我们不太可能更改此行为。

更新:请注意,此行为在 v3 中没有改变。

when you have two interfaces on the same class: will it will be the same class if I register the second interface on the same class?

不,不会。这实际上会导致 Torn Registration ,这是 Diagnostic Services 的东西警告。基本上,如果您这样做:

container.Register<IFoo, FooBar>(Lifestyle.Singleton);
container.Register<IBar, FooBar>(Lifestyle.Singleton);

在这种情况下,容器将为 FooBar 解析两个单独的实例.那是因为 Simple Injector 专注于注册(抽象),而不是实现(例如,与 Unity 相比,它以相反的方式工作)。如果您恰好需要 1 FooBar ,您必须执行以下操作:

var registration = Lifestyle.Singleton.CreateRegistration<FooBar>(container);

container.AddRegistration(typeof(IFoo), registration);
container.AddRegistration(typeof(IBar), registration);

在您的情况下,这意味着您必须这样做:

var registration = Lifestyle.Singleton.CreateRegistration<UserService>(container);

container.AddRegistration(typeof(IUserService), registration);
container.AddRegistration(typeof(UserService), registration);

container.RegisterCollection(typeof(IObserver<>),
new[] { typeof(IObserver<>).Assembly });

// Simple Injector v2.x syntax
container.RegisterManyForOpenGeneric(typeof(IObserver<>),
container.RegisterAll,
typeof(IObserver<>).Assembly);

关于c# - 在简单注入(inject)器中注册为单例的具有两个接口(interface)的类的行为是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28112061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com