Search code examples
autofacasp.net5

How to resolve open generic service without registering type object?


I am trying to figure out how to resolve for a generic service without registering the type. I need to do this at runtime as there are too many different types that will need to be passed to this service and several others.

I used RegisterAssemblyTypes to register several services. One of those services is MongoService, which is registered as MongoService<>.

I see the service listed in list of the scope's registrations. When I attempt to resolve the service as

_productService = diScope.Resolve<MongoService<Product>>(new NamedParameter("mongoSettings", productCollection));

I get the ComponentNotRegisteredException below:

Autofac.Core.Registration.ComponentNotRegisteredException
  HResult=0x80131500
  Message=The requested service 'RecWebEditor.Services.MongoService`1[
  [bn.pds.ren.RENAPI.objects.ren.Product, RENAPI, Version=2020.2.4.8, Culture=neutral, PublicKeyToken=null]]'
   has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(),
    or use the ResolveOptional() method to resolve an optional dependency.
  Source=Autofac

I know that Autofac doesn't have the Product type registered, since I have not registered it.

I was expecting this to get resolved the same way as the Microsoft Logging ILogger.

I suspect I am missing something obvious.

Thanks


Solution

  • I think there are a few things of note here:

    I think the answer is going to be:

    Instead of registering MongoService<T> using assembly scanning, use the open generics registrations. It'll look something like this, but read the docs I linked to get more understanding. This is an example of what it might look like, not copy/paste ready for the needs of your app.

    builder.RegisterGeneric(typeof(MongoService<>))
           .AsSelf();
    

    After that, see if you can resolve your MongoService<Product>. I don't think when you register an open generic using those extensions that you have to register the T inside the MongoService<T>.

    Here are some example unit tests showing the generic registrations in action, in case you want to see more real code.