WhenTargetHas<>绑定不能按预期工作

时间:2015-08-19 14:07:33

标签: ninject

我使用这个构造函数获得了这个类:

public AbstractAddon([Configuration]object configuration)
{
    this.configuration = configuration;
}

如您所见,它有一个带ConfigurationAttribute的构造函数参数。 ConfigurationAttribute是:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter, Inherited=true)]
public class ConfigurationAttribute : Attribute { }

我的模块如下:

public override void Load()
{
    this.Bind(b => b.FromAssembliesMatching("*")
        .SelectAllClasses()
        .InheritedFrom(typeof(UIExtensibility.AbstractAddon))
        .BindAllBaseClasses()
        .Configure(c => c.InSingletonScope())
    );

    this.Bind<object>().ToProvider<ConfigurationProvider>().WhenTargetHas<UIExtensibility.ConfigurationAttribute>();
}

然后,我的object提供商是:

private class AddonProvider : IProvider<object>
{

    public object Create(IContext context)
    {
        return "configuration settings";
    }

}

当我执行kernel.GetAll<UIExtensibility.AbstractAddon>())时,我希望使用提供程序来创建&#34;配置&#34; object个实例 - 但永远不会调用提供程序。

你能帮助我吗? 我很感激你的帮助。

谢谢大家。

2 个答案:

答案 0 :(得分:1)

参数的属性不会“继承”到派生类的构造函数。没有继承发生,相反,派生类的构造函数覆盖(和扩展)基类的构造函数。

使用继承的类 - 属性

您可以改用:

[AttributeUsage(AttributeTargets.Class, Inherited=true)]
public class ConfigurationAttribute : Attribute { }

[Configuration]
public abstract class AbstractAddon
{
    private readonly object configuration;

    protected AbstractAddon(object configuration)
    {
        this.configuration = configuration;
    }
}    

public class FooAddon : AbstractAddon
{
    public FooAddon(object configuration)
        : base(configuration)
    {
    }
}

和绑定:

this.Bind(b => b.FromAssembliesMatching("*")
    .SelectAllClasses()
    .InheritedFrom(typeof(UIExtensibility.AbstractAddon))
    .BindAllBaseClasses()
    .Configure(c => c.InSingletonScope())
);

this.Bind<object>().ToProvider<ConfigurationProvider>()
    .WhenClassHas<UIExtensibility.ConfigurationAttribute>

其他基于属性的方法

ninject wiki还描述了其他基于属性的方法:

  • WhenTargetHas<SomeAttribute> =检查注入的参数是否具有属性
  • WhenTargetHas<SomeAttribute> =检查注入的属性是否具有属性

现在可以继承属性及其属性,因此这可能是一种解决方案:

public abstract class AbstractAddon
{
    [Inject]
    [Configuration]
    public object Configuration { get; set;}
}

this.Bind<object>().ToProvider<ConfigurationProvider>()
    .WhenMemberHas<ConfigurationAttribute>

无属性约定

不是检查属性,因为你想要注入配置的所有类型都是从AbstractAddon派生的,为什么不以此为基础?根本不需要属性。 我怀疑这应该有效:

this.Bind<object>().ToProvider<ConfigurationProvider>()
    .WhenInjectedInto<AbstractAddon>();

如果它不起作用,您也可以使用以下方式滚动自己的约定:

this.Bind<object>().ToProvider<ConfigurationProvider>()
    .When(... condition goes here...);

答案 1 :(得分:0)

我已经测试了第一种方法,它运行良好。

NInject模块:

public class AddonsModule : Ninject.Modules.NinjectModule
{
    public override void Load()
    {
        this.Bind(b => b.FromAssembliesMatching("*")
            .SelectAllClasses()
            .InheritedFrom(typeof(UIExtensibility.AbstractAddon))
            .BindAllBaseClasses()
            .Configure(c => c.InSingletonScope())
        );

        this.Bind<object>().ToProvider<ConfigurationProvider>().WhenClassHas<UIExtensibility.ConfigurationAttribute>();
    }

    private class ConfigurationProvider : IProvider<object>
    {

        public object Create(IContext context)
        {
            //...
        }
    }
}

我的抽象类:

[Configuration]
public abstract class AbstractAddon : IAddon
{

    //...
}