c# - ServiceProvider.GetServices with Open Types - Stack Overflow

admin2025-04-16  5

I am trying to retrieve all instances of a registered service that implements an IMyInterface<T> where T is a base class so I can read all the implementations of T being handled.

So far, I have tried:

var registeredInstances = _serviceProvider.GetServices(typeof(IMyInterface<MyBaseClass>)).ToList();
var registeredInstances = _serviceProvider.GetServices(typeof(IMyInteface<>)).ToList();

First one returns no results, second one errors as GetServices cannot use open types.

What am I missing here?

I am trying to retrieve all instances of a registered service that implements an IMyInterface<T> where T is a base class so I can read all the implementations of T being handled.

So far, I have tried:

var registeredInstances = _serviceProvider.GetServices(typeof(IMyInterface<MyBaseClass>)).ToList();
var registeredInstances = _serviceProvider.GetServices(typeof(IMyInteface<>)).ToList();

First one returns no results, second one errors as GetServices cannot use open types.

What am I missing here?

Share Improve this question edited Feb 4 at 5:55 Qiang Fu 9,4071 gold badge6 silver badges16 bronze badges asked Feb 4 at 0:20 MalekaiMalekai 4510 bronze badges 4
  • And how you registered types? – Selvin Commented Feb 4 at 0:52
  • Ive registered an implementation of the interface public class MyInterfaceClass : IMyInterface<MyBaseImplementation> public class MyBaseImplementation : BaseClass Services.AddScoped<IMyInterface<MyBaseImplementation>, MyInterfaceClass>() So I'd have assumed _serviceProvider.GetServices(typeof(IMyInterface<MyBaseClass>)).ToList() would have returned something – Malekai Commented Feb 4 at 0:55
  • No, it's different class... They are unrelated unless there is some kind of variance – Selvin Commented Feb 4 at 0:57
  • Is T covariant for IMyInterface<T>? – Johnathan Barclay Commented Feb 4 at 11:21
Add a comment  | 

1 Answer 1

Reset to default 0

You could try following sample:

    public interface IMyInterface<T> where T : BaseClass
    {
        void Process(T item);
    }
    public abstract class BaseClass { }

    public class Derived1 : BaseClass { }
    public class Derived2 : BaseClass { }

    public class Service1 : IMyInterface<Derived1>
    {
        public void Process(Derived1 item) { Console.WriteLine("Service1 processing Derived1"); }
    }
    public class Service2 : IMyInterface<Derived2>
    {
        public void Process(Derived2 item) { Console.WriteLine("Service2 processing Derived2"); }
    }
...
builder.Services.AddTransient<IMyInterface<Derived1>, Service1>();
builder.Services.AddTransient<IMyInterface<Derived2>, Service2>();

To get all services

            var serviceType = typeof(IMyInterface<>);
            var derivedTypes = typeof(BaseClass).Assembly.GetTypes()
                .Where(t => typeof(BaseClass).IsAssignableFrom(t) && t != typeof(BaseClass));

            var implementations = new List<object>();

            foreach (var derivedType in derivedTypes)
            {
                var genericType = serviceType.MakeGenericType(derivedType);
                var services = _serviceProvider.GetServices(genericType);
                implementations.AddRange(services);
            }
            var registeredInstances = implementations.ToArray();

Test result:

转载请注明原文地址:http://www.anycun.com/QandA/1744744200a86998.html