作者:清皮皮 | 来源:互联网 | 2023-05-25 12:59
我有以下课程:
public class UserService : IUserService, IObserver
我已注册IUserService
为Singleton UserService
.之后我以IObserver
这种方式注册:
container.RegisterManyForOpenGeneric(typeof(IObserver<>),
container.RegisterAll,
typeof(IObserver<>).Assembly);
所以现在如果我注入IEnumerable
我的复合模式,当我将枚举时,我会得到与解析时相同的对象IUserService
吗?
它似乎以这种方式工作(只有一个UserService
存在的对象),至少如果我解决了IEnumerable
第一个问题.我无法在文档中找到它,但这是Simple Injector支持的功能还是可以随时更改的巧合?如果是,那么我猜这个行为对于任何两个或更多接口是相同的,不一定是开放通用的?
1> Steven..:
您看到的行为是设计的,并在文档中描述了container.RegisterCollection(Type,IEnumerable)方法(RegisterAll
在v2.x中):
注册一组serviceTypes,每次枚举已解析的serviceType集合时,其实例将被懒惰地解析.基础集合是一个流,它将根据每个调用的特定注册生活方式返回单个实例IEnumerator.Current
.类型在集合中出现的顺序与项目注册的顺序完全相同,即已解析的集合是确定性的.
尽管API文档说明了这一点,但我必须承认文档对此并不十分清楚.还有其他地方描述了这种行为,但这些信息有点埋藏在文档的深处.
但基本上,API旨在允许:
container.Register(Lifestyle.Transient);
container.Register(Lifestyle.Scoped);
container.Register(Lifestyle.Singleton);
container.RegisteCollection(new[] {
typeof(MailLogger),
typeof(SqlLogger),
typeof(FileLogger),
typeof(ILogger)
});
这个配置有一组ILogger
实现,其中collection(MailLogger
)中的第一个元素将是一个瞬态(如果LifestyleSelectionBehavior
没有被覆盖),第二个(SqlLogger
)将是Per Request,第三个(FileLogger
)将是一个单例,并且第四个元素将解决一个DefaultLogger
瞬态.
这是一个可以随时改变的巧合吗?
不,这是记录,测试和支持的.虽然我们(根据定义)会在下一个主要版本中引入重大变化,但我们不太可能改变这种行为.
更新:请注意,此行为在v3中未更改.
当你在同一个类上有两个接口时:如果我在同一个类上注册第二个接口,它将是同一个类吗?
不,它不会.事实上,这将导致Torn Registration,这是Diagnostic Services警告的内容.基本上,如果你这样做:
container.Register(Lifestyle.Singleton);
container.Register(Lifestyle.Singleton);
在这种情况下,容器将解析两个单独的实例FooBar
.这是因为Simple Injector专注于注册(抽象),而不是实现(例如,与Unity相比,反过来相反).如果您只需要1 FooBar
,则必须执行以下操作:
var registration = Lifestyle.Singleton.CreateRegistration(container);
container.AddRegistration(typeof(IFoo), registration);
container.AddRegistration(typeof(IBar), registration);
在你的情况下,这意味着你必须这样做:
var registration = Lifestyle.Singleton.CreateRegistration(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);