[英]Ninject. Optional Injection
我有啟用/禁用功能的全局標志。 我想根據某些標志注入一些依賴項。 某些功能需要大量構建的類,因此如果標志的值為 false,則我想注入 null,否則為實際依賴項。 Ninject 不允許注入 null。 還有其他選擇嗎?
更新:構造函數 arguments 可以用OptionalAttribute
屬性裝飾。 在這種情況下,如果沒有找到相應的綁定,則注入 null。 這里有一個問題:我無法驗證目標 class 是否可以正確構建。 我對每個公共依賴項進行了測試,以驗證它是否可以成功構建。 如果標志的值為 true,當使用OptionalAttribute
屬性裝飾的依賴項無法正確構造時,我將無法找到錯誤。 我只想在綁定級別上管理它。
您可以通過使用工廠方法(即ToMethod
)綁定來改變注入行為,並且可以通過配置容器的AllowNullInjection
設置來允許注入空值。
另一種選擇是使用工廠方法並提供輕量級虛擬 object 而不是重量級 class。 如果您使用的是接口,這將很簡單,只需實現不執行任何操作的接口即可。 您甚至可以使用 FakeItEasy 等 mocking 框架為您構建這些假人。 這里的好處是,假人使特殊行為對客戶端透明,即客戶端不需要檢查null
等。
使用工廠方法的示例,加上AllowNullInjection
和 nulls:
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) {}
}
還有一個根據標志替換輕量級 object 的示例:
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) {}
}
注入 null 通常不是一個明智的主意。 這將通過檢查 object 是否為 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 Object ,它完全不做任何事情並注入這個而不是 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();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.