2012-05-14 57 views
0

爲什麼IContainer.IsRegistered(Type serviceType)添加註冊?爲什麼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與空數組初始化。 當我發現這種行爲時,我有點困惑。

回答

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); 
              } 
             }; 
     } 
    }