核心问题
我的问题的核心是学习正确的语法,以将未绑定的泛型作为类型参数提供给将传递给typeof
运算符的另一个泛型类型:
typeof(IEnumerable<IEnumerable<>>))
什么是正确的语法?
忍者用例
我想在 Ninject 中实现以下目标。
假设我有以下接口和实现:
public interface IParser<in TIn, out TOut>
{
TOut Parse(TIn input);
}
public class IntParser : IParser<string, int>
{
public int Parse(string input)
{
return int.Parse(input);
}
}
public class SpaceSeperatedParser<T> : IParser<string, IEnumerable<T>>
{
private readonly IParser<string, T> _itemParser;
public SpaceSeperatedParser(IParser<string, T> itemParser)
{
_itemParser = itemParser;
}
public IEnumerable<T> Parse(string input)
{
return input.Split(' ').Select(_itemParser.Parse);
}
}
我想将这些类型绑定到我的 Ninject 内核中。但是,我很难SpaceSeperatedParser
以通用方式绑定,因此我不必枚举所有可能的T
类型。
从语法上讲,这似乎应该是我正在寻找的。不幸的是,它甚至在语法上都不正确!
IKernel kernel = new StandardKernel();
kernel.Bind(typeof (IParser<string, int>)).To(typeof (IntParser));
// does not work -- syntax error
kernel
.Bind(typeof(IParser<string, IEnumerable<>>))
.To(typeof(SpaceSeperatedParser<>));
// works, but is not generic
// kernel
// .Bind(typeof (IParser<string, IEnumerable<int>>))
// .To(typeof (SpaceSeperatedParser<int>));
// should return a SpaceSeperatedParser<int>, with IntParser as _itemParser
var parser = kernel.Get<IParser<string, IEnumerable<int>>>();
Console.WriteLine(string.Join(", ", parser
.Parse("23 42 9 32 10")
.Select(i => i + 5)));
Ninject 甚至支持这个吗?