我想将null
传递给已解析的类构造函数参数之一。但是,ParameterOverride
不接受null作为值(从实现看似null
内部被解释为"未解析")。
我也尝试使用默认值提供参数或没有此参数的重载构造函数 - 但在这种情况下Unity总是抱怨,我没有为此参数提供值。
示例代码:
unityContainer.Resolve<MyClass>(new ParameterOverride(myField, null));
答案 0 :(得分:1)
您可以使用一些方法来注入空依赖项(例如注入null的InjectionFactory
),但我没有看到ParameterOverride
的方法。可能有一种简单的方法可以做到这一点,但我没有立刻想到它。
但是,使用ParameterOverride
注入null的一种方法是创建一个专门注入null的InjectionParameterValue
。这将绕过Unity的空检查。它可能看起来像这样:
public class NullInjectionParameterValue : InjectionParameterValue
{
public NullInjectionParameterValue(Type parameterType)
{
this.ParameterTypeName = parameterType.GetTypeInfo().Name;
}
public override bool MatchesType(Type t)
{
return !t.IsValueType || (Nullable.GetUnderlyingType(t) != null);
}
public override IResolverPolicy GetResolverPolicy(Type typeToBuild)
{
return new LiteralValueDependencyResolverPolicy(null);
}
public override string ParameterTypeName { get; }
}
public class NullInjectionParameterValue<TParameter>
: NullInjectionParameterValue where TParameter : class
{
public NullInjectionParameterValue()
: base(typeof(TParameter))
{
}
}
然后你可以像这样使用它:
container.Resolve<MyClass>(
new ParameterOverride("myField", new NullInjectionParameterValue<string>()));
答案 1 :(得分:0)
此类行为并非Unity独有 - 大多数DI容器不允许您注入null
(除非您手动干预或扩展容器以允许它)。
来自Microsoft's Unity 2.1 documentation(因为Unity 5在Google中没有文档结果):
您无法提供
null
作为要注入的值。您必须显式提供InjectionParameter,与类型一样。
注入服务时,使它们成为null
是不合逻辑的。这意味着需要null
检查代码遍布整个代码以处理这种情况。相反,我们保护成员变量,使它们永远不会null
使代码变得健壮。
public class MyService : IMyService
{
// Can only be set by the constructor
private readonly IMyClass myClass;
public MyService(IMyClass myClass)
{
// Can never set to null
if (myclass == null)
throw new ArgumentNullException(nameof(myClass));
this.myClass = myClass;
}
public void DoSomething()
{
// Null checking is not required here (or anywhere else in
// this class) because we are guaranteed to have an instance
// when this object is instantiated.
// if (this.myClass != null)
this.myClass.DoSomething();
}
}
那么当我们想要代表 nothing 时我们该怎么办?使用Null Object Pattern来使用具有 null行为的类来满足IMyClass
要求。
public class NullMyClass : IMyClass
{
public void DoSomething()
{
// The logical "null" behavior is to do nothing here
}
}
现在NullMyClass
可与Unity一起使用来表示IMyClass
的无操作。
new MyService(null); // Throws NullReferenceException (desired to make the code robust)
new MyService(new MyClass()); // Implements concrete behavior
new MyService(new NullMyClass()) // Implements null behavior (no-op)
unityContainer.Resolve<IMyClass>(new ParameterOverride(myField, new NullMyClass()));
参考:How can I inject a property only if the value is non-null at runtime using Unity?