当我调用Autofac的.Resolve方法时,我得到一个异常,说明我的组件尚未注册,但我不确定原因。
错误:
抛出异常: 'Autofac.Core.Registration.ComponentNotRegisteredException'中 Autofac.dll其他信息:请求的服务 'Nt.Bot.Sdi.Secure.SdiApiAccess.Login.ISdiLoginApi'尚未 注册。要避免此异常,请将组件注册到 提供服务,检查服务注册使用 IsRegistered(),或使用ResolveOptional()方法来解析 可选的依赖。
我按如下方式注册我的服务:
public void Configure(ContainerBuilder diContainer)
{
diContainer.RegisterType<SdiLoginApi>().As<ISdiLoginApi>();
}
上面的configure方法在我的global.asax.cs中调用。请注意,NtDialogContext.DiContainer是一个静态属性:
var containerBuilder = new ContainerBuilder();
new BotDependencyInjectionConfig().Configure(containerBuilder);
NtDialogContext.DiContainer = containerBuilder.Build();
然后我尝试按如下方式加载服务。这是我得到错误的地方(我也尝试了Resolve的'通用'版本):
using (var containerScope = NtDialogContext.DiContainer.BeginLifetimeScope())
{
var loginApi = (ISdiLoginApi)containerScope.Resolve(typeof(ISdiLoginApi));
}
如果我在调用.Resolve之前使用调试器检查containerScope,我看到我的组件在containerScope.ComponentRegistry.Registrations中:
{Activator = SdiLoginApi(ReflectionActivator),Services = [Nt.Bot.Sdi.Secure.SdiApiAccess.Login.ISdiLoginApi],终身= Autofac.Core.Lifetime.CurrentScopeLifetime,Sharing = None,Ownership = OwnedByLifetimeScope}
也许我误解了一些关于Autofac的事情?为什么我在尝试解决时遇到错误?
我正在使用Autofac v4.1.1,它是Bot Builder v3.5的依赖项。
答案 0 :(得分:0)
这里的问题根本与Autofac无关。如果有人遇到同样的问题,我会发布答案。
我们使用MEF(Managed Extensibility Framework)加载“插件”程序集。作为这个加载过程的一部分,我们有代码迭代文件夹中的DLL并将它们加载到AppDomain中。
public static IEnumerable<Assembly> GetClientAssembliesRelativeToAssembly(Assembly asm, string subPath = null, string wildcard = "Sdi*.dll")
{
var path = subPath != null
? Path.Combine(Path.GetDirectoryName(asm.CodeBase.Substring(8)), subPath)
: Path.GetDirectoryName(asm.CodeBase.Substring(8));
foreach (var dll in Directory.GetFiles(path, wildcard))
{
yield return Assembly.LoadFile(dll);
}
}
上面的问题是我们使用“LoadFile”而不是“LoadFrom”。当我们使用LoadFile时,程序集将直接从您指定的位置加载。但是这会导致DLL的一个版本驻留在/ bin /中而另一个版本驻留在/ Temporary ASP.NET文件/文件夹中。
然后我们遇到了Autofac将一种类型与另一种类型(ISdiLoginApi与ISdiLoginApi)进行比较的情况。它们应该是相同的,但不是因为一个程序集是由MEF(和我们的“LoadFile”调用)加载而另一个是直接引用驻留在/ Temporary ASP.NET文件/中。所以ISdiLoginApi!= ISdiLoginApi和AutoFac.Resolve()失败。
所以解决方案是在我们的程序集加载代码中使用LoadFrom()。这样,所有程序集都从同一个地方加载,Autofac可以正常工作。