1

Core Problem

At the core of my problem is learning the correct syntax for providing an unbound generic as a type parameter to another generic type that will be pass to the typeof operator:

typeof(IEnumerable<IEnumerable<>>))

What is the proper syntax for this?

Ninject Use Case

I would like to achieve the following in Ninject.

Supposed I have the following interfaces and implementations:

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);
    }
}

I would like to bind these types into my Ninject kernel. However, I am having a hard time binding SpaceSeperatedParser in a generic manner, so that I don't have to enumerate every possible T type.

Syntactically, this seems like this should do that I am looking for. Unfortunately, it is not even syntactically correct!

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)));

Does Ninject even support this?

Joel Verhagen
  • 5,110
  • 4
  • 38
  • 47
  • "(...) the open generic syntax (and the .NET type system) does not have a way to express a type which has a nested type arg open. You need to resolve this by getting back to top level class that has an open arg, only. " --> See http://stackoverflow.com/questions/16764603/ninject-binding-by-convention-not-working-with-generics-types?rq=1 – BatteryBackupUnit Oct 10 '13 at 11:13
  • "What is the proper syntax for this?". This is: `typeof(IEnumerable<>).MakeGenericType(typeof(IEnumerable<>))`. – Steven Oct 10 '13 at 20:42

0 Answers0