Kernel.Get和构造器注入的Ninject不同的行为 [英] Ninject different behaviour between Kernel.Get and Constructor Injection
问题描述
我有什么:
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屋!