我有启用/禁用功能的全局标志。我想注入一些依赖于某些标志的依赖项。一些特性需要大量构造的类,所以如果标志的值为false,我想注入null,否则注入实际的依赖项。Ninject不允许注入null。还有没有别的选择?
更新:构造函数参数可以用OptionalAttribute
属性来修饰。在这种情况下,如果没有找到相应的绑定,则会注入null。这里有一个问题:我不能验证目标类是否可以正确构造。我对每个公共依赖项都有一个测试,用来验证它是否可以成功构建。如果标志的值为true,当用OptionalAttribute
属性修饰的依赖项不能正确构造时,我将无法找到错误。我只想在绑定级别上管理它。
发布于 2011-07-01 20:02:09
您可以通过使用工厂方法(即ToMethod
)进行绑定来改变注入行为,并且可以通过配置容器的AllowNullInjection
设置来允许注入空值。
另一种选择是使用工厂方法,并提供一个轻量级的虚拟对象,而不是您的重量级类。如果您正在使用接口,这将是简单的,只要有接口的实现什么都不做就行了。您甚至可以使用FakeItEasy之类的模拟框架来为您构造这些虚拟对象。这里的好处是,虚拟对象使特殊行为对客户端透明,即客户端不需要检查null
等。
使用工厂方法以及AllowNullInjection
和空值的示例:
public void Configure()
{
bool create = true;
IKernel kernel = new StandardKernel();
kernel.Settings.AllowNullInjection = true;
kernel.Bind<IFoo>().ToMethod(ctx => create ? ctx.Kernel.Get<Foo>() : null);
DependendsOnIFoo depFoo = kernel.Get<DependendsOnIFoo>();
}
private interface IFoo {}
private class Foo : IFoo {}
private class DependendsOnIFoo
{
public DependendsOnIFoo(IFoo foo) {}
}
还有一个示例,其中根据标志替换轻量级对象:
public void Configure()
{
bool heavy = true;
IKernel kernel = new StandardKernel();
kernel.Bind<IFoo>()
.ToMethod(ctx => heavy ? ctx.Kernel.Get<HeavyFoo>() : (IFoo)new DummyFoo());
DependendsOnIFoo depFoo = kernel.Get<DependendsOnIFoo>();
}
private interface IFoo {}
private class HeavyFoo : IFoo {}
private class DummyFoo : IFoo { }
private class DependendsOnIFoo
{
public DependendsOnIFoo(IFoo foo) {}
}
发布于 2011-07-01 20:12:44
注入null通常不是一个明智的想法。这将污染您的代码,检查对象是否为空,如以下代码所示:
public interface IFoo
{
void Do();
}
public class Foo : IFoo
{
public void Do()
{
DoSomething();
}
}
public class UglyNullCheckingBar
{
IFoo foo;
public Bar(IFoo foo)
{
this.foo = foo;
}
public void Do()
{
if (this.foo != null)
{
this.foo.Do();
}
}
}
在这种情况下,更好的方法是实现一个绝对不做任何事情的null对象,并注入这个对象而不是Null。这可以让你的代码保持整洁。
public class NullFoo : IFoo
{
public void Do() {}
}
public class Bar
{
IFoo foo;
public Bar(IFoo foo)
{
this.foo = foo;
}
public void Do()
{
this.foo.Do();
}
}
https://stackoverflow.com/questions/6546657
复制相似问题