多个RegisterAll注册使用与SimpleInjector相同的单例集

我正在使用Simple Injector为电子商务项目构建一个插件系统。 我正在使用RegisterAll来注册IPaymentProviderIResourceRegistrar所有实现(以及更多)。

但这每次都会创建一个新实例。 建议在每种类型上使用RegisterSingle 。 但是在这种情况下如何实现这一目标呢?

 private static void RegisterMultipleUnderOneInterface( Container container, string name) { IEnumerable pluginRegistrations = from dll in finder.Assemblies from type in dll.GetExportedTypes() where type.GetInterfaces().Any(i => i.Name == name) where !type.IsAbstract where !type.IsGenericTypeDefinition select type; if (pluginRegistrations.Any()) { var @interface = pluginRegistrations.ElementAt(0).GetInterfaces() .First(i => i.Name == name); foreach (Type type in pluginRegistrations) { // HERE: register the type single somehow. } container.RegisterAll(@interface, pluginRegistrations); } } 

container.RegisterSingle(type)不起作用,因为同一接口固有的类型( IPaymentProviderIResourceRegistrar )。 实现类的IPaymentProvider具有不带参数的构造函数, IResourceRegistrar具有参数。

我不想做这样的事情,而是违背了IoC容器的目的

 var constructor = type.GetConstructors()[0]; switch (name) { case "IResourceRegistrar": container.RegisterSingle(type, () => { return constructor.Invoke(new object[ { container.GetInstance()}); }); break; case "IPaymentProvider": default: container.RegisterSingle(type, () => { return constructor.Invoke(new object[] { }); }); break; } 

如何在没有丑陋开关的情况下将这些注册为单身?

也许我误解了,但RegisterSingle应该可以工作。 你应该能够做到这一点:

 var types = ... container.RegisterAll(types); foreach (var type in types) { container.RegisterSingle(type, type); } 

更新:

所以你要做的是自动化以下配置:

 // A, B, C and D implement both I1 and I2. container.RegisterSingle(); container.RegisterSingle(); container.RegisterSingle(); container.RegisterSingle(); container.RegisterAll(typeof(A), typeof(B), typeof(C), typeof(D)); container.RegisterAll(typeof(A), typeof(B), typeof(C), typeof(D)); 

这通常是自动化的方法。 这样做有四个步骤:

  1. 找到要注册的所有类型。
  2. 将找到的类型注册为singleton。
  3. 将类型列表注册为I1集合。
  4. 将类型列表注册为I2集合。

这看起来像这样:

 // using SimpleInjector.Extensions; Type[] singletons = FindAllTypesToRegister(); foreach (Type type in singletons) { container.RegisterSingle(type, type); } container.RegisterAll(typeof(I1), singletons); container.RegisterAll(typeof(I2), singletons); 

但是,由于您尝试将其拆分为两个步骤并创建一个可以处理每个步骤的通用方法,因此您必须忽略何时已注册具体的单例类型。 你可以这样做:

  • 通过捕获RegisterSingle抛出的exception来忽略RegisterSingle
  • 通过在调用RegisterSingle之前设置container.Options.AllowOverridingRegistrations = true覆盖现有RegisterSingle (之后禁用它将是最安全的)。