1

这是我的场景:

 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 类中。

我想做类似 Line * with 的事情Ninject。您可能知道问题是在解决类之前,GetType()返回Null. 那么,如何在需要时仅解决列表中的一项?

可以Ninject做这样的事情还是我必须改变我的 DI 容器?

4

2 回答 2

0

这是一个先有鸡还是先有蛋的问题:除非你得到值,否则你不知道类型。您只能通过将额外信息添加到事先已知的列表中来解决此问题。

这非常适合作为System.ComponentModel.Composition程序集一部分的Lazy<T, TMetadata>

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);
于 2013-07-24T19:27:43.417 回答
-1

您可以使用System.Linq 命名空间中提供的OfType扩展方法。

var dog = _animals.OfType<Dog>().First();
于 2013-07-24T18:35:29.217 回答