10

有没有办法在不使用属性的情况下在 Ninject 2 中使用属性注入[Inject]?这会在将使用它连接的类中创建对 Ninject 的依赖项,我更愿意避免对 IoC 容器产生不必要的依赖项,这就是我最终更频繁地使用构造函数注入的原因。

我想这同样适用于方法注入

4

3 回答 3

9

我按照鲁本的提示发布了一篇关于如何实现这一目标的小博客文章,但这里有一个快速的答案:

创建自定义属性:

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>();
于 2010-07-19T15:33:55.280 回答
4

您可以在创建时将另一个 [attribute] 类型传递给内核,它可以用来代替InjectAttribute,但您仍然必须集中引用一些 OOTB。

最近有一个类似的问题关于在没有属性的情况下进行 PI - 没有 OOTB(直接在流畅的配置界面中)放入自定义扫描仪,但是可扩展点(在构建时添加实现 Ninject 接口的组件)如果查找给定属性不是您想要的,则指示该方面如何工作的内核)在那里根据约定而不是配置确定注入的位置 - 没有什么可以阻止您将扫描修改为仅基于属性名称(因此它不一定必须位于中心位置)。

请注意,一般来说,构造函数注入有很多原因是好的,包括这个,并且让你的代码容器不可知是很重要的(即使你目前对一个很满意!)

于 2010-07-13T07:41:40.087 回答
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。

于 2010-08-13T22:02:18.213 回答