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
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.
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.
User contributions licensed under CC BY-SA 3.0