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
{
//...
}
我用这个构造函数得到了这个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
{
//...
}