c# - 注入(inject)。可选注入(inject)

标签 c# ninject

我有启用/禁用功能的全局标志。我想根据某些标志注入(inject)一些依赖项。某些功能需要大量构造的类,因此如果标志的值为 false 则我想注入(inject) null,否则注入(inject)实际的依赖项。 Ninject 不允许注入(inject) null。还有其他选择吗?

更新:构造函数参数可以用 OptionalAttribute 属性修饰。在这种情况下,如果没有找到相应的绑定(bind),则会注入(inject) null。这里有一个问题:我无法验证目标类是否可以正确构造。我对每个公共(public)依赖项进行了测试,以验证它是否可以成功构建。如果标志的值为真,当用 OptionalAttribute 属性装饰的依赖项无法正确构造时,我将无法找到错误。我只想在绑定(bind)级别上管理它。

最佳答案

您可以通过使用工厂方法(即 ToMethod)进行绑定(bind)来改变注入(inject)行为,并且可以通过配置容器的 AllowNullInjection 设置来允许注入(inject)空值。

另一种选择是使用工厂方法并提供轻量级虚拟对象而不是重量级类。如果您正在使用接口(interface),这将很简单,只需实现不执行任何操作的接口(interface)即可。您甚至可以使用模拟框架(例如 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) {}
} 

关于c# - 注入(inject)。可选注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6546657/

相关文章:

c# - 通过 knockout 显示 ajax 数据

c# - 什么能比并发集合更好地解决这种多线程场景

c# - Ninject:如何在 "ashx"文件中不使用 Ninject 并且仍然没有得到异常?

c# - Ninject.ActivationException : Error activating IMainLicense 错误

c# - NLog 找不到或加载配置文件

vb.net - 依赖注入(inject) - 我不明白!

c# - 在过滤掉某些属性的同时序列化 JSON.NET JObject

c# - 更改字典键的最佳方法

c# - UserPrincipal.Save() 导致 ObjectDisposedException

Ninject 拦截 - 移植到 Ninject 3.0 时的重大更改