程序.cs:
var config = GetConfiguration();
var host = CreateHostBuilder(config, args).Build();
host.Run();
return 0;
IConfiguration GetConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
return builder.Build();
}
IHostBuilder CreateHostBuilder(IConfiguration configuration, string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureAppConfiguration(x => x.AddConfiguration(configuration))
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseContentRoot(Directory.GetCurrentDirectory());
});
Sturtup.cs:
public void ConfigureServices(IServiceCollection services)
{
services
.AddCustomMvc(Configuration)
.AddSwaggerGen()
.AddCustomDbContext(Configuration);
}
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule(new ApplicationModule(Configuration.GetConnectionString("mssql")!));
builder.RegisterModule(new MetiatorModule());
builder.RegisterModule(new DomainEventMediatorModule(<IServiceCollection or IServiceProvider should be here>));
}
public class DomainEventMediatorModule
: Autofac.Module
{
public static IServiceScopeFactory? ServiceScopeFactory { get; set; }
protected override void Load(ContainerBuilder builder)
{
Func<DomainEventMediator> domainEventMediatorCreation = () =>
{
DomainEventMediator domainEventMediator = new();
var domainEventHandlerTypes = Assembly
.GetAssembly(typeof(UserCreatedDomainEventHandler))!
.GetTypes()
.Where(x => x.GetInterfaces()
.Any(y => y.IsGenericType
&& y.GetGenericTypeDefinition() == typeof(IDomainEventHandler<>)));
using (var scope = ServiceScopeFactory?.CreateScope())
{
foreach (var handlerType in domainEventHandlerTypes)
{
var domainEventType = handlerType
.GetInterfaces()
.First()
.GetGenericArguments()
.First();
var registereMethod = typeof(DomainEventMediator)
.GetMethod(nameof(DomainEventMediator.Register))!
.MakeGenericMethod(domainEventType!);
var handlerInstance = ActivatorUtilities.CreateInstance(scope!.ServiceProvider, handlerType)!; // StackOverflowException here
registereMethod.Invoke(domainEventMediator, new object[] { handlerInstance });
}
}
return domainEventMediator;
};
builder.Register(c => domainEventMediatorCreation())
.As<IDomainEventMediator>()
.SingleInstance();
}
}
我需要将服务或服务提供商作为参数发送给 DomainEventMediatorModule 构造函数,但是,我需要来自 ApplicationModule 模块的依赖项。
那么,我怎样才能获得包含所有需要的服务的 ServiceCollection 或 ServiceProvider?
我尝试从 ConfigureServices 方法获取服务,但它没有来自模块的服务。 此外,我无法在 ConfigureContainer 方法中调用
builder.Build()
,因为 Autofac 在执行此方法后第二次调用它。