Search code examples
c#genericsioc-containersimple-injector

Simple Injector fallback Registration of open generic not working


I have the following

class GetData : Query
class Data : Result

class IHandler<TIn,TOut>
class IQueryHandler<TQuery,TResult> : IHandler<TQuery, IEnumerable<TResult>>
class DefaultQueryHandler<TQuery,TResult> : IQueryHander<TQuery,TResult>

Container.RegisterConditional(
    typeof(IHandler<,>),
    typeof(DefaultQueryHandler<,>),
    c => c!.Handled
)

I have followed the guide here https://simpleinjector.readthedocs.io/en/latest/advanced.html#registration-of-open-generic-types and thought that

Container.GetInstance<IHandler<GetData,IEnumerable<Data>>> should instantiate DefaultQueryHandler<GetData, Data>

But I get 'No registration found for IHandler'

Thank you


Solution

  • I tried to reproduce your error, but when I run it in a console application everything works as expected. Here is the code I used to reproduce:

    using System;
    using System.Collections.Generic;
    using SimpleInjector;
    
    class Query { }
    class Result { }
    
    class GetData : Query { }
    class Data : Result { }
    
    class IHandler<TIn, TOut> { }
    class IQueryHandler<TQuery, TResult> : IHandler<TQuery, IEnumerable<TResult>> { }
    class DefaultQueryHandler<TQuery, TResult> : IQueryHandler<TQuery, TResult> { }
    
    class Program
    {
        static void Main(string[] args)
        {
            var container = new Container();
    
            container.RegisterConditional(
                typeof(IHandler<,>),
                typeof(DefaultQueryHandler<,>),
                c => !c.Handled);
    
            var handler = container.GetInstance<IHandler<GetData, IEnumerable<Data>>>();
    
            Console.WriteLine(handler.GetType().FullName);
            Console.ReadLine();
        }
    }
    

    The GetInstance call returns the following closed type:

    DefaultQueryHandler<GetData, Data>