这里有一些示例代码
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>();
}
GetAssemblies()方法加载并返回应用程序引用的程序集数组。所有模块都已注册并显示在servicelocator中。但是,当尝试使用以下代码解析接口时,出现ComponentNotRegisteredException:
_dlMembershipParserService =
ServiceLocator.Current.GetInstance<IDLMembershipParserService>();
这里是其中一个模块的示例:
public class ServiceModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<DLMembershipParserService>().As<IDLMembershipParserService>();
builder.RegisterType<DLMembershipExporterService>().As<IDLMembershipExporterService>();
}
}
有人有什么想法吗?程序集已加载,每个要加载的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);
}
}
但是唯一有效的是对模块的引用,就像这样:
builder.RegisterModule<ServiceModule>();
但是这不是我想要的。我需要能够添加模块并使它们被应用程序发现。
我感谢对此有任何见识。
谢谢
GetAssemblies()方法加载并返回该应用程序引用的程序集数组。
您是调用AppDomain.CurrentDomain.GetAssemblies()
还是将程序集动态加载到您的应用程序中?如果是,请在调用DLMembershipParserService
时检查包含GetAssemblies()
及其相关类型的程序集是否已加载。
请注意,并非所有referenced程序集都在应用程序启动时加载。组件在首次使用时加载。如果您在代码中引用该模块,则可能是该原因。
如果需要强制加载所有引用的程序集,则必须使用Assembly.GetReferencedAssemblies
方法来查找所有引用的程序集并将它们加载到您的应用程序中。
因此,我从.NET Core的角度发现了我需要做的事情,以便从.NET Core动态发现和加载程序集。
需要一个nuget包来加载.NET Core程序集,以便可以在运行时解析所有已注册的类型。程序包称为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);
}
}
这解决了我在加载程序集和注册类型后解决注册类型的问题。