WhenTargetHas<> 绑定未按预期工作

WhenTargetHas<> Binding Does not Work as Expected

我用这个构造函数得到了这个class:

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>()) 时,我希望提供程序用于创建 "configuration" object 实例 - 但从未调用提供程序。

你能帮帮我吗? 非常感谢你的帮助。

谢谢大家。

参数的属性不是 "inherited" 派生 class 的构造函数。没有发生继承,派生 class 的构造函数覆盖(并扩展)基 class.

的构造函数

改用继承的 Class-属性

您可以改用这个:

[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...);

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

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)
        {
            //...
        }
    }
}

还有我的摘要class:

[Configuration]
public abstract class AbstractAddon : IAddon
{

    //...
}