Я пытаюсь использовать Ninject для реализации каскадного внедрения в класс, содержащий поле IList. Кажется, что, если я не укажу каждую привязку для использования в методе kernel.Get, свойство IList всегда внедряется со списком одного объекта по умолчанию.
Следующий код VSTest иллюстрирует проблему. Первый тест не пройден, поскольку в поле IList содержится один объект MyType с именем = null. Второй тест пройден, но мне пришлось специально указать Ninject, какие аргументы конструктора использовать. Я использую последнюю сборку из проекта ninject.web.mvc для MVC 3.
Специально ли Ninject относится к IList по-другому или есть лучший способ справиться с этим? Обратите внимание, что это кажется проблемой только при использовании IList. Создание пользовательского объекта коллекции, заключающего в себя IList, работает, как и ожидалось, в первом тесте.
[TestClass()]
public class NinjectTest
{
[TestMethod()]
public void ListTest_Fails_NameNullAndCountIncorrect()
{
var kernel = new Ninject.StandardKernel(new MyNinjectModule());
var target = kernel.Get<MyModel>();
var actual = target.GetList();
// Fails. Returned value is set to a list of a single object equal to default(MyType)
Assert.AreEqual(2, actual.Count());
// Fails because MyType object is initialized with a null "Name" property
Assert.AreEqual("Fred", actual.First().Name);
}
[TestMethod()]
public void ListTest_Passes_SeemsLikeUnnecessaryConfiguration()
{
var kernel = new Ninject.StandardKernel(new MyNinjectModule());
var target = kernel.Get<MyModel>(new ConstructorArgument("myGenericObject", kernel.Get<IGenericObject<MyType>>(new ConstructorArgument("myList", kernel.Get<IList<MyType>>()))));
var actual = target.GetList();
Assert.AreEqual(2, actual.Count());
Assert.AreEqual("Fred", actual.First().Name);
}
}
public class MyNinjectModule : NinjectModule
{
public override void Load()
{
Bind<IList<MyType>>().ToConstant(new List<MyType> { new MyType { Name = "Fred" }, new MyType { Name = "Bob" } });
Bind<IGenericObject<MyType>>().To<StubObject<MyType>>();
}
}
public class MyModel
{
private IGenericObject<MyType> myGenericObject;
public MyModel(IGenericObject<MyType> myGenericObject)
{
this.myGenericObject = myGenericObject;
}
public IEnumerable<MyType> GetList()
{
return myGenericObject.GetList();
}
}
public interface IGenericObject<T>
{
IList<T> GetList();
}
public class StubObject<T> : IGenericObject<T>
{
private IList<T> _myList;
public StubObject(IList<T> myList)
{
_myList = myList;
}
public IList<T> GetList()
{
return _myList;
}
}
public class MyType
{
public String Name { get; set; }
}