存在Autofac注册,但servicelocator引发ComponentNotRegisteredException

存在Autofac注册,但servicelocator引发ComponentNotRegisteredException,exception,autofac,registration,Exception,Autofac,Registration,下面是一些示例代码 public void RegisterDependencies() { var builder = new ContainerBuilder(); ConfigureModules(builder); ConfigureProfiles(builder); var container = builder.Build(); Servic

下面是一些示例代码

public void RegisterDependencies()
        {
            var builder = new ContainerBuilder();

            ConfigureModules(builder);
            ConfigureProfiles(builder);

            var container = builder.Build();

            ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(container));
        }

protected virtual void ConfigureModules(ContainerBuilder builder)
        {
            var assemblies = GetAssemblies();
            {
                builder.RegisterAssemblyModules(assemblies);
            }
        }

        protected virtual void ConfigureProfiles(ContainerBuilder builder)
        {
            var profiles = GetTypes<Profile>();

            builder.RegisterInstance(new MapperConfiguration(cfg => cfg.AddMaps(profiles)).CreateMapper())
                .As<IMapper>();
        }
public void RegisterDependencies()
{
var builder=new ContainerBuilder();
配置模块(生成器);
配置配置文件(生成器);
var container=builder.Build();
SetLocatorProvider(()=>新的AutofacServiceLocator(容器));
}
受保护的虚拟void配置模块(ContainerBuilder builder)
{
var assemblies=GetAssemblies();
{
builder.RegisterAssemblyModule(程序集);
}
}
受保护的虚拟void配置配置文件(ContainerBuilder builder)
{
var profiles=GetTypes();
builder.RegisterInstance(新的MapperConfiguration(cfg=>cfg.AddMaps(profiles)).CreateMapper()
.As();
}
getAssemblys()方法加载并返回应用程序引用的程序集数组。所有模块都已注册并显示在servicelocator中。但是,当尝试使用以下代码解析接口时,我得到ComponentNotRegisteredException:

_dlMembershipParserService =
                ServiceLocator.Current.GetInstance<IDLMembershipParserService>();
\u dlMembershipParserService=
ServiceLocator.Current.GetInstance();
以下是其中一个模块的示例:

public class ServiceModule : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<DLMembershipParserService>().As<IDLMembershipParserService>();
            builder.RegisterType<DLMembershipExporterService>().As<IDLMembershipExporterService>();
        }
    }
公共类服务模块:自动传真模块
{
受保护的覆盖无效负载(ContainerBuilder builder)
{
builder.RegisterType().As();
builder.RegisterType().As();
}
}
有人有什么想法吗?程序集已加载,并且每个加载的dll只有一个程序集

我还尝试了以下代码,得到了相同的结果:

protected virtual void ConfigureModules(ContainerBuilder builder)
        {
            var modules = GetTypes<IModule>().Select(m => (IModule)Activator.CreateInstance(m));

            foreach (var module in modules)
            {
                builder.RegisterModule(module);
            }
        }
受保护的虚拟void配置模块(ContainerBuilder builder)
{
var modules=GetTypes().Select(m=>(IModule)Activator.CreateInstance(m));
foreach(模块中的var模块)
{
生成器注册表模块(模块);
}
}
但唯一有效的是对模块的had引用,如下所示:

builder.RegisterModule()

但这不是我想要的。我需要能够添加模块,并有他们的应用程序发现

我很欣赏对这一点的任何见解

谢谢

getAssemblys()方法加载并返回应用程序引用的程序集数组

您正在调用AppDomain.CurrentDomain.GetAssemblys()
还是将程序集动态加载到应用程序中?如果是,请检查在调用
GetAssemblies()
时是否加载了包含
DLMembershipParserService
及其依赖类型的程序集

请注意,并非所有引用的程序集都在应用程序启动时加载。程序集在首次使用时加载。这可能就是为什么如果在代码中引用该模块,它就会工作

如果需要强制加载所有引用的程序集,则必须使用
Assembly.getReferencedAssembly
方法查找所有引用的程序集并将其加载到应用程序中


因此,我从.NET Core的角度发现了我需要做什么,以便从.NET Core动态发现和加载程序集

加载.NET核心程序集需要一个nuget包,以便在运行时解析所有注册的类型。该包名为System.Runtime.Loader

一旦安装,我就能够根据类型信息成功地发现程序集,然后在运行时加载、注册和解析类型

以下是一些示例代码:

public override Type[] GetTypes<T>()
{
    var assemblyPath = _assemblyHelper.GetEntryAssemblyLocation();
    var path = _pathHelper.GetDirectoryName(assemblyPath);

    var files = _fileHelper.GetFiles(path, "Tss.DLMembership.*.dll");

    return files.SelectMany(file => _assemblyHelper.LoadFile(file).GetTypes()
        .Where(t => typeof(T).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract))
    .ToArray();
}

public class AssemblyHelper : IAssemblyHelper
{
    public string GetEntryAssemblyLocation()
    {
        return AppContext.BaseDirectory;
    }

    public Assembly LoadFile(string fileName)
    {
        return AssemblyLoadContext.Default.LoadFromAssemblyPath(fileName);
    }
}
public覆盖类型[]GetTypes()
{
var assemblyPath=_assemblyHelper.GetEntryAssemblyLocation();
var path=\u pathHelper.GetDirectoryName(assemblyPath);
var files=_fileHelper.GetFiles(路径“Tss.DLMembership.*.dll”);
return files.SelectMany(文件=>\u assemblyHelper.LoadFile(文件).GetTypes()
其中(t=>typeof(t).IsAssignableFrom(t)和&!t.IsInterface和&!t.IsAbstract))
.ToArray();
}
公共类AssemblyHelper:IAssemblyHelper
{
公共字符串GetEntryAssemblyLocation()
{
返回AppContext.BaseDirectory;
}
公共程序集加载文件(字符串文件名)
{
返回AssemblyLoadContext.Default.LoadFromAssemblyPath(文件名);
}
}

这解决了我在加载程序集和注册类型后解析注册类型的问题。

我使用此行加载RegisterModules使用的程序集:返回文件。选择(file=>_assemblyHelper.LoadFile(file)).ToArray();如果所有程序集都已加载,则可以在模块中设置断点,并查看它们是否被命中。此外,如果您检查
ComponentNotRegisteredException
最内部异常的错误消息,您将发现哪个服务未注册。但是,最内部异常表示该服务尚未注册,在加载的两个模块中都遇到断点…我一定是缺少了什么?有时可能会在未注册的从属服务上引发
ComponentNotRegisteredException
。例如,
Class1
使用
Class2
,但是
Class2
未注册。您可能需要阅读最内部异常的完整消息,并找出activator用于创建服务实例的构造函数和类型。以及它失败的原因。