首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >九号对象。可选注入

九号对象。可选注入
EN

Stack Overflow用户
提问于 2011-07-01 18:19:27
回答 2查看 5K关注 0票数 19

我有启用/禁用功能的全局标志。我想注入一些依赖于某些标志的依赖项。一些特性需要大量构造的类,所以如果标志的值为false,我想注入null,否则注入实际的依赖项。Ninject不允许注入null。还有没有别的选择?

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-07-01 20:02:09

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

另一种选择是使用工厂方法,并提供一个轻量级的虚拟对象,而不是您的重量级类。如果您正在使用接口,这将是简单的,只要有接口的实现什么都不做就行了。您甚至可以使用FakeItEasy之类的模拟框架来为您构造这些虚拟对象。这里的好处是,虚拟对象使特殊行为对客户端透明,即客户端不需要检查null等。

使用工厂方法以及AllowNullInjection和空值的示例:

代码语言:javascript
复制
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) {}
}

还有一个示例,其中根据标志替换轻量级对象:

代码语言:javascript
复制
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) {}
} 
票数 17
EN

Stack Overflow用户

发布于 2011-07-01 20:12:44

注入null通常不是一个明智的想法。这将污染您的代码,检查对象是否为空,如以下代码所示:

代码语言:javascript
复制
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。这可以让你的代码保持整洁。

代码语言:javascript
复制
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();
    }
}
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6546657

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档