How to resolve open generic service without registering type object?

0

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

autofac
asp.net5
asked on Stack Overflow Feb 1, 2021 by mhsimkin

2 Answers

0

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.

answered on Stack Overflow Feb 2, 2021 by Travis Illig
0

I know that the below is overly simplified, but it works for to scan the assembly and then register the generics.

protected void RegisterGenericServices(ContainerBuilder builder, Assembly executingAssembly)
{
    var services = executingAssembly.GetTypes()
        .Where(t => t.GetInterfaces().Contains(typeof(IService))
                    && t.IsGenericType);

    foreach (var service in services) builder.RegisterGeneric(service).AsSelf();
}

I will end up with too many services that will need to be registered.

Once again, thank you.

answered on Stack Overflow Feb 2, 2021 by mhsimkin

User contributions licensed under CC BY-SA 3.0