这是我的情景:
public class Foo
{
private readonly List<Lazy<IAnimal>> _animals;
public Foo(List<Lazy<IAnimal>> animals )
{
_animals = animals;
}
public void Bark()
{
//Line: *
var dog = _animals.First(p => p.GetType() == typeof (Dog)).Value;
}
Public void Mio()
{
//Line: *
var dog = _animals.First(p => p.GetType() == typeof (Cat)).Value;
}
}
public class Dog:IAnimal
{
}
public class Cat:IAnimal
{
}
public interface IAnimal
{
}
问题:
这里动物名单被懒惰地注入Foo类。
我想用Ninject
做一些像Line *这样的事情。您可能知道问题是在解析课程之前,GetType()
会返回Null
。那么我怎样才能随时解析列表中的一个项目?
Ninject
可以做这样的事情还是我必须改变我的DI容器?
答案 0 :(得分:0)
这是鸡和蛋的问题:除非你得到这个值,否则你不知道它的类型。您只能通过向事先已知的列表中添加额外信息来解决此问题。
这非常适合Lazy<T, TMetadata>,它是 System.ComponentModel.Composition 程序集的一部分:
public class Foo
{
private readonly List<Lazy<IAnimal, Type>> _animals;
public Foo(List<Lazy<IAnimal, Type>> animals)
{
_animals = animals;
}
public void Bark()
{
var dog = _animals.First(p => p.Metadata == typeof(Dog)).Value;
}
}
<强>更新强>
正如我在评论中所说,我不是Ninject专家,但大多数事情都可以通过框架完成,即使没有内置的支持。这就是我认为你的注册看起来像。我可能有Ninject语法错误,但看起来有点像这样:
var list = new List<Lazy<IAnimal, Type>>();
list.Add(new Lazy<IAnimal, Type>(() => kernel.Get<Dog>(), typeof(Dog)));
list.Add(new Lazy<IAnimal, Type>(() => kernel.Get<Pussy>(), typeof(Pussy)));
list.Add(new Lazy<IAnimal, Type>(() => kernel.Get<Horse>(), typeof(Horse)));
kernel.Bind<List<Lazy<IAnimal, Type>>().ToConstant(list);
答案 1 :(得分:-1)
您可以使用System.Linq命名空间中提供的OfType扩展方法。
var dog = _animals.OfType<Dog>().First();