[英]Multiple RegisterAll registrations using the same set of singletons with SimpleInjector
我正在使用 Simple Injector 為電子商務項目構建插件系統。 我正在使用RegisterAll
來注冊IPaymentProvider
和IResourceRegistrar
(以及更多)的所有實現。
但這每次都會創建一個新實例。 這里建議在每種類型上使用RegisterSingle
。 但是在這種情況下如何實現這一目標?
private static void RegisterMultipleUnderOneInterface(
Container container, string name)
{
IEnumerable<Type> 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)
不起作用,因為來自同一接口( IPaymentProvider
或IResourceRegistrar
)的固有類型。 IPaymentProvider
實現類具有不帶參數的構造函數, IResourceRegistrar
具有參數。
我不想做這樣的事情,它反而違背了 IoC 容器的目的
var constructor = type.GetConstructors()[0];
switch (name)
{
case "IResourceRegistrar":
container.RegisterSingle(type, () =>
{
return constructor.Invoke(new object[
{
container.GetInstance<ILanguageService>()});
});
break;
case "IPaymentProvider":
default:
container.RegisterSingle(type, () =>
{
return constructor.Invoke(new object[] { });
});
break;
}
如何在沒有丑陋開關的情況下將這些注冊為單例?
也許我誤解了,但 RegisterSingle 應該可以工作。 你應該能夠做到這一點:
var types = ...
container.RegisterAll<IInterface>(types);
foreach (var type in types)
{
container.RegisterSingle(type, type);
}
更新:
所以你要做的是自動化以下配置:
// A, B, C and D implement both I1 and I2.
container.RegisterSingle<A>();
container.RegisterSingle<B>();
container.RegisterSingle<C>();
container.RegisterSingle<D>();
container.RegisterAll<I1>(typeof(A), typeof(B), typeof(C), typeof(D));
container.RegisterAll<I2>(typeof(A), typeof(B), typeof(C), typeof(D));
這通常是自動執行此操作的方法。 所以做四個步驟:
I1
集合。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
拋出的異常來忽略RegisterSingle
。RegisterSingle
之前通過設置container.Options.AllowOverridingRegistrations = true
覆蓋現有RegisterSingle
(之后禁用它是最安全的)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.