Dependency injection Ninject 2.0:不带属性的属性注入

Dependency injection Ninject 2.0:不带属性的属性注入,dependency-injection,ioc-container,ninject,ninject-2,Dependency Injection,Ioc Container,Ninject,Ninject 2,有没有一种方法可以在Ninject 2中使用属性注入而不使用[Inject]属性?这会在类中创建对Ninject的依赖,该类将使用Ninject进行连接,我更喜欢避免对IoC容器产生不必要的依赖,这就是为什么我更经常地使用构造函数注入 我想这同样适用于方法注入您可以在创建时将另一个[attribute]类型传递给内核,它可以用来代替InjectAttribute,但是您仍然需要集中引用某些东西 最近有一个类似的问题,关于在没有属性的情况下进行PI,没有OOTB(如fluent配置界面上的直接操作

有没有一种方法可以在Ninject 2中使用属性注入而不使用
[Inject]
属性?这会在类中创建对Ninject的依赖,该类将使用Ninject进行连接,我更喜欢避免对IoC容器产生不必要的依赖,这就是为什么我更经常地使用构造函数注入


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

您可以在创建时将另一个[attribute]类型传递给内核,它可以用来代替
InjectAttribute
,但是您仍然需要集中引用某些东西

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


请注意,总的来说,构造函数注入有很多好处,包括这一点,保持代码容器的不可知性很重要(即使您目前对此感到满意!)

我遵循了Ruben的提示,并发布了一个关于如何实现这一点的小文章,但下面是一个快速答案:

创建自定义属性:

public class InjectHereAttribute : Attribute
{
}
目标类现在将如下所示:

public class Samurai
{
    [InjectHere]        
    public IWeapon Context { get; set; }
}
现在必须将Ninject配置为使用自定义属性,这可以通过创建一个识别自定义属性的IInjectHeuristic实现来实现:

public class CustomInjectionHeuristic : NinjectComponent, IInjectionHeuristic, INinjectComponent, IDisposable
{
    public new bool ShouldInject(MemberInfo member)
    {
        return member.IsDefined(
          typeof(InjectHereAttribute),
          true);
    }
}
最后,使用Components集合将此行为添加到Ninject内核中,它将沿着现有组件运行,即IINjectHeuristic的默认实现,这意味着可以使用默认属性或自定义属性

// Add custom inject heuristic
kernel.Components.Add<IInjectionHeuristic, CustomInjectionHeuristic>();
//添加自定义注入启发式
cornel.Components.Add();

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

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;
      }
}
公共密封类MyInjectionHeuristic:NinjectComponent,IIinjectHeuristic
{
私有静态只读IList
_PropertyInjectable=
新名单
{
类型(IMyService),
};
/// 
///返回一个值,该值指示是否应注入指定的成员。
/// 
///有关成员。
///如果应注入成员,则为True;否则为false。
公共图书馆应注册(会员信息会员)
{
var info=作为PropertyInfo的成员;
if(member==null | | info==null)
返回false;
if(info.CanWrite)
返回_propertyInjectable.Contains(info.PropertyType);
if(this.Settings==null)
返回false;
var propList=member.GetCustomAttributes(this.Settings.InjectAttribute,true);
返回propList.Length>0;
}
}
创建内核时:

var heuristics = _kernel.Components.Get<ISelector>().InjectionHeuristics;
   heuristics.Add(new MyInjectionHeuristic());
var heuristics=\u kernel.Components.Get().InjectionHeuristics;
Add(newmyinjectionheuristic());

当您希望通过属性注入其他类型时,只需向IList添加其他类型。

该链接不再存在(因此说明了为什么复制/粘贴并归功于原始作者总是比链接到原始作者更好)。您是否有其他资源来描述此问题的原始答案?@BTownTKD您是对的。我在答案中添加了示例并更改了断开的链接。谢谢!这看起来非常有用。