Ninject 2.0:没有属性的属性注入

时间:2010-07-12 18:53:56

标签: dependency-injection ioc-container ninject ninject-2

有没有办法在不使用[Inject]属性的情况下在Ninject 2中使用Property Injection?这会在使用它连接的类中创建对Ninject的依赖,我更愿意避免对IoC容器有不必要的依赖,这就是我最常使用Constructor Injection的原因。

我猜这同样适用于Method Injection

3 个答案:

答案 0 :(得分:7)

我按照鲁本的提示,发布了一篇关于如何实现这一点的小blog post,但这是快速回答:

创建自定义属性:

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内核,它将沿现有组件运行,即IInjectionHeuristic的默认实现,这意味着可以使用默认属性或自定义属性。

// Add custom inject heuristic
kernel.Components.Add<IInjectionHeuristic, CustomInjectionHeuristic>();

答案 1 :(得分:4)

您可以在创建时将另一个[attribute]类型传递给内核,而不是InjectAttribute,但您仍需要集中引用OOTB。

最近有一个关于没有属性的PI的类似问题 - 没有OOTB(直接在流畅的配置界面上)放入自定义扫描程序但是扩展点(你添加一个实现Ninject接口的组件)你构建你的内核,决定如果找到一个给定的属性是不是你想要的那个方面是如何工作的那里根据约定优于配置确定注入的位置 - 没有什么能阻止你修改扫描基于只是一个属性名称(所以它不一定要住在中心位置)。

请注意,一般情况下,构造函数注入有很多原因,包括这一点,并且保持代码容器不可知是很重要的(即使你现在对它感到满意!)

答案 2 :(得分:3)

我能够使用启发式类完成此任务:

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添加其他类型。