Kernel.Get和构造器注入的Ninject不同的行为 [英] Ninject different behaviour between Kernel.Get and Constructor Injection

查看:139
本文介绍了Kernel.Get和构造器注入的Ninject不同的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有什么:

public interface IBla
{
}

public class Bla1 : IBla
{
}

public class Bla : IBla
{
}

public class Consumer
{
    private readonly IBla[] _array;

    public Consumer(IBla[] array)
    {
        _array = array;
    }
}

public static class NinjectExtensions
{
      public class BindListExpression<TElement>
      {
          private readonly IKernel _kernel;
          private readonly List<Type> _types = new List<Type>();

          public BindListExpression(IKernel kernel)
          {
              _kernel = kernel;
          }

          public BindListExpression<TElement> ImplementedBy<T>() where T : TElement
          {
              var type = typeof(T);

              _kernel.Bind<T>().To(type);
              _types.Add(type);

              return this;
          }

          public void Bind()
          {
              Func<TElement[]> createObjects = () =>
              {
                  var sourceArray = new TElement[_types.Count];
                  for (var i = 0; i < _types.Count; i++)
                  {
                      var value = _kernel.Get(_types[i]);
                      sourceArray[i] = (TElement)value;
                  }
                  return sourceArray;
              };

              _kernel.Bind<TElement[]>().ToMethod(x => createObjects().ToArray());
              _kernel.Bind<List<TElement>>().ToMethod(x => (createObjects().ToList()));
              _kernel.Bind<IEnumerable<TElement>>().ToMethod(x => createObjects().ToList());
          }
      }
      public static BindListExpression<T> ListOf<T>(this IKernel kernel)
      {
          return new BindListExpression<T>(kernel);
      }
  }



用法:

Usage:

// Binds items in the given order as a list (Ninject does not guarantee the given order so I use this mechanism).
kernel.ListOf<IBla>()
    .ImplementedBy<Bla1>()
    .ImplementedBy<Bla>()
    .Bind();

var consumer = kernel.Get<Consumer>(); // result: consumer._array is empty?! --> what is imo wrong
var array = kernel.Get<IBla[]>(); // result: Bla1, Bla --> correct



为什么不Ninject产生获取℃之间相同的结果; IBLA []>?()和构造函数的参数 IBLA []

推荐答案

通过构造函数注入,ninject转换的构造函数参数 IBLA [] IResolutionRoot.GetAll< IBLA>( ).ToArray()。这就是如何为多喷射的支持来实现。因此,这不可能导致一个构造函数,请求 IResolutionRoot.Get< IBLA []方式>() - 但它仍然是你可以手动执行

With constructor injection, ninject translates the ctor parameter IBla[] to a IResolutionRoot.GetAll<IBla>().ToArray(). That's how support for multi-injection is implemented. So it's not possible for a ctor-request to result in a IResolutionRoot.Get<IBla[]>() - but it's still something you can do manually.

这是所有集合类型这ninject真正转化为多级喷射(AFAIR阵列,的IList 的IEnumerable ,而不是的ICollection )。

This is true for all collection-types which ninject translates to multi-injection (AFAIR array, IList, IEnumerable, but not ICollection).

我建议你使用其他Collection接口(如的ICollection )或集合实现作为构造函数的参数。这将导致构造函数注入和 IResolutionRoot.Get 通话。

I'd recommend using another collection interface (like ICollection) or collection implementation as constructor parameter. This will result in consistent behavior for ctor-injection and IResolutionRoot.Get calls.

这篇关于Kernel.Get和构造器注入的Ninject不同的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆