有没有办法在不使用属性的情况下在 Ninject 2 中使用属性注入[Inject]
?这会在将使用它连接的类中创建对 Ninject 的依赖项,我更愿意避免对 IoC 容器产生不必要的依赖项,这就是我最终更频繁地使用构造函数注入的原因。
我想这同样适用于方法注入
有没有办法在不使用属性的情况下在 Ninject 2 中使用属性注入[Inject]
?这会在将使用它连接的类中创建对 Ninject 的依赖项,我更愿意避免对 IoC 容器产生不必要的依赖项,这就是我最终更频繁地使用构造函数注入的原因。
我想这同样适用于方法注入
我按照鲁本的提示发布了一篇关于如何实现这一目标的小博客文章,但这里有一个快速的答案:
创建自定义属性:
public class InjectHereAttribute : Attribute
{
}
目标类现在看起来像这样:
public class Samurai
{
[InjectHere]
public IWeapon Context { get; set; }
}
现在必须将 Ninject 配置为使用自定义属性,这可以通过创建识别自定义属性的 IInjectionHeuristic 实现来完成:
public class CustomInjectionHeuristic : NinjectComponent, IInjectionHeuristic, INinjectComponent, IDisposable
{
public new bool ShouldInject(MemberInfo member)
{
return member.IsDefined(
typeof(InjectHereAttribute),
true);
}
}
最后使用 Components 集合将此行为添加到 Ninject Kernel 中,它将沿着现有组件运行,即 IInjectionHeuristic 的默认实现,这意味着可以使用默认或自定义属性。
// Add custom inject heuristic
kernel.Components.Add<IInjectionHeuristic, CustomInjectionHeuristic>();
您可以在创建时将另一个 [attribute] 类型传递给内核,它可以用来代替InjectAttribute
,但您仍然必须集中引用一些 OOTB。
最近有一个类似的问题关于在没有属性的情况下进行 PI - 没有 OOTB(直接在流畅的配置界面中)放入自定义扫描仪,但是可扩展点(在构建时添加实现 Ninject 接口的组件)如果查找给定属性不是您想要的,则指示该方面如何工作的内核)在那里根据约定而不是配置确定注入的位置 - 没有什么可以阻止您将扫描修改为仅基于属性名称(因此它不一定必须位于中心位置)。
请注意,一般来说,构造函数注入有很多原因是好的,包括这个,并且让你的代码容器不可知是很重要的(即使你目前对一个很满意!)
我能够使用启发式类来完成此操作:
public sealed class MyInjectionHeuristic : NinjectComponent, IInjectionHeuristic
{
private static readonly IList<Type>
_propertyInjectible =
new List<Type>
{
typeof(IMyService),
};
/// <summary>
/// Returns a value indicating whether the specified member should be injected.
/// </summary>
/// <param name="member">The member in question.</param>
/// <returns><c>True</c> if the member should be injected; otherwise <c>false</c>.</returns>
public bool ShouldInject(MemberInfo member)
{
var info = member as PropertyInfo;
if( member == null || info == null )
return false;
if (info.CanWrite)
return _propertyInjectible.Contains(info.PropertyType);
if( this.Settings == null )
return false;
var propList = member.GetCustomAttributes(this.Settings.InjectAttribute, true);
return propList.Length > 0;
}
}
创建内核时:
var heuristics = _kernel.Components.Get<ISelector>().InjectionHeuristics;
heuristics.Add(new MyInjectionHeuristic());
当您想通过属性注入其他类型时,只需将其他类型添加到 IList。