问题描述
我想弄清楚如何在不注册类型的情况下解析通用服务。我需要在运行时执行此操作,因为有太多不同类型需要传递给此服务和其他几个服务。
我使用 RegisterAssemblyTypes 来注册多个服务。其中一项服务是 MongoService,它注册为 MongoService。
我看到范围注册列表中列出的服务。当我尝试将服务解析为
_productService = diScope.Resolve<MongoService<Product>>(new NamedParameter("mongoSettings",productCollection));
我得到下面的 ComponentNotRegisteredException:
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
我知道 Autofac 没有注册 Product 类型,因为我还没有注册它。
我希望能像 Microsoft Logging ILogger 一样解决这个问题。
我怀疑我遗漏了一些明显的东西。
谢谢
解决方法
我认为这里有几点值得注意:
- 您无法解决未注册的问题。
- 截至今天(2021 年 2 月 2 日),您无法使用程序集扫描注册开放泛型。 It's a PR actively being worked,so it's coming 但它不在这里。
我认为答案是:
不是使用程序集扫描注册 MongoService<T>
,而是 use the open generics registrations。它看起来像这样,但阅读我链接的文档以获得更多理解。这是一个可能外观示例,而不是为满足您的应用需求而准备的复制/粘贴。
builder.RegisterGeneric(typeof(MongoService<>))
.AsSelf();
在那之后,看看您是否可以解决您的MongoService<Product>
。我不认为当您使用这些扩展注册开放泛型时,您必须在 T
内注册 MongoService<T>
。
Here are some example unit tests 显示正在运行的通用注册,以防您想查看更多真实代码。
,我知道以下内容过于简化,但它适用于扫描程序集然后注册泛型。
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();
}
我最终会得到太多需要注册的服务。
再次感谢您。