0

为什么 IContainer.IsRegistered(Type 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 使用空数组进行初始化。当我发现这种行为时,我有点困惑。

4

1 回答 1

0

我发现上述行为是设计使然

这是避免注入空数组的解决方法。
它使用反射,因此使用这种方法需要您自担风险。
请注意,它会降低分辨率性能。您只需要注册以下模块:

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);
            }
        };
    }
}
于 2012-05-15T10:24:12.173 回答