为什么IContainer.IsRegistered(类型serviceType)会添加注册?
Type serviceType = typeof (string[]);
int rc = container.ComponentRegistry.Registrations.Count();
container.IsRegistered(serviceType);
int rc2 = container.ComponentRegistry.Registrations.Count();
Assert.AreEqual(rc, rc2);
上述行为可能会产生以下副作用:
public class Test
{
public Entity[] Entities { get; set; }
}
//...
var bldr = new ContainerBuilder();
bldr.RegisterModule<ArraysInjectionGuardModule>();
var container = bldr.Build();
var t = new Test();
container.InjectProperties(t);
Assert.IsNull(t.Entities);
因为container.InjectProperties(...);
调用container.IsRegistered(..)
并传递typeof(Entity[])
作为参数,所以使用空数组初始化t.Entities。
当我发现这种行为时,我有点困惑。
答案 0 :(得分:0)
我发现上述行为是by design
这是一种避免注入空阵列的解决方法 它使用反射,因此请自行承担风险 请注意降低分辨率性能。 您只需注册以下模块:
containerBuilder.RegisterModule<ArraysInjectionGuardModule>();
class ArraysInjectionGuardModule : Module
{
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry,
IComponentRegistration registration)
{
registration.Activating += (s, e) =>
{
var ts = e.Component.Services.Single() as TypedService;
if (ts != null && ts.ServiceType.IsArray &&
!e.Context.IsRegistered(ts.ServiceType.GetElementType()))
{
FieldInfo t = e.GetType().GetField("_instance",
BindingFlags.Instance | BindingFlags.NonPublic);
t.SetValue(e, null);
}
};
}
}