c# - 向 ASP.NET Core 注册现有的 Autofac 容器
问题描述
我目前正在构建一个通过 TCP 使用自定义协议的服务器应用程序。此服务器应用程序当前使用 Autofac 进行依赖注入。
不过最近,我在解决方案中添加了一个 ASP.NET Core 项目,以提供一个 HTTP API 来操作服务器应用程序,主要是提供一个管理 Web 应用程序。
Autofac 为 ASP.NET Core 项目提供集成,但我很难弄清楚如何告诉 ASP.NET Core 服务配置使用我已经构建的 Autofac 服务容器,以便我的 TCP 服务和 HTTP API可以从同一个容器中解析服务。
Autofac为此提供了文档:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// Add services to the collection.
services.AddMvc();
// Create the container builder.
var builder = new ContainerBuilder();
builder.Populate(services);
builder.RegisterType<MyType>().As<IMyType>();
this.ApplicationContainer = builder.Build();
// Create the IServiceProvider based on the container.
return new AutofacServiceProvider(this.ApplicationContainer);
// ^
// This is where I'd like to insert my container ━━━━┛
}
该示例仅展示了如何从头开始为 ASP.NET Core 应用程序构建一个完整的容器,但现在展示了如何重用现有容器。
在 an 上使用该ConfigureServices
方法在IWebHostBuilder
这里不起作用,因为它的返回类型为void
,所以我不能在AutofacServiceProvider
那里返回 an 。
这是我启动应用程序的方式:
var containerBuilder = new ContainerBuilder();
// Here's where I register all my services
containerBuilder.RegisterModule(new ApplicationModule());
var container = containerBuilder.Build();
using (var scope = container.BeginLifetimeScope())
{
var server = scope.Resolve<TcpServer>();
var isService = args.Contains("--winservice");
// Construct the HTTP API
var builder = WebHost
.CreateDefaultBuilder(args.Where(arg => arg != "--winservice").ToArray())
.ConfigureServices(collection =>
{
// Not sure what to do here?
// I can call `collection.AddAutofac` here, not sure what that does
})
.UseStartup<ApplicationAPI>();
// Start the HTTP API
if (isService)
{
// Run as a Win Service
builder.Build().RunAsCustomService(server);
}
else
{
await server.Start();
// Do not run as a Win Service
builder.Build().Run();
}
}
那么如何使用同一个容器来解决我的 TCP 服务器和 HTTP API 中的依赖关系呢?
谢谢!
解决方案
您还可以尝试提供聚合服务提供程序,类似于此处提供的服务提供程序(https://github.com/kephas-software/kephas/blob/master/src/Kephas.Composition.DependencyInjection/Composition/DependencyInjection/AggregatedServiceProvider。 ):
/// <summary>
/// An aggregated service provider.
/// </summary>
public class AggregatedServiceProvider : IServiceProvider, IDisposable
{
private readonly IList<IServiceProvider> innerServiceProviders;
/// <summary>
/// Initializes a new instance of the <see cref="AggregatedServiceProvider"/> class.
/// </summary>
/// <param name="innerServiceProviders">A variable-length parameters list containing inner
/// service providers.</param>
public AggregatedServiceProvider(params IServiceProvider[] innerServiceProviders)
{
this.innerServiceProviders = innerServiceProviders.ToList();
}
/// <summary>
/// Gets the service object of the specified type.
/// </summary>
/// <param name="serviceType">An object that specifies the type of service object to get.</param>
/// <returns>
/// A service object of type <paramref name="serviceType">serviceType</paramref>. -or- null if
/// there is no service object of type <paramref name="serviceType">serviceType</paramref>.
/// </returns>
public object GetService(Type serviceType)
{
foreach (var serviceProvider in this.innerServiceProviders)
{
var service = serviceProvider.GetService(serviceType);
if (service != null)
{
return service;
}
}
return null;
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged
/// resources.
/// </summary>
public void Dispose()
{
foreach (var serviceProvider in this.innerServiceProviders)
{
(serviceProvider as IDisposable)?.Dispose();
}
this.innerServiceProviders.Clear();
}
}
然后,将您在配置服务中的代码更改为:
return new AgregegatedServiceProvider(new ServiceProvider(services), myAutofacContainer);
缺点是来自 ASP.NET Core 的服务对您的 Autofac 容器不可用,但是,正如我所见,这对您来说应该不是问题。
推荐阅读
- node.js - 在 Angular 中,如何解析和提取具有复杂结构 (JSON) 的 HTTP 响应?
- java - 如何使用带有 Spring Security 5.1+ 的 google OIDC 对用户进行身份验证
- javascript - 如何将我的输入字段和按钮向上对齐以使其与其他按钮内联?
- google-analytics - gatsby-plugin-google-analytics 允许回调或设置要求选项
- visual-studio-code - VS 代码扩展 - 传播捕获的键绑定
- python - 为什么别名在 Pandas 库中某些方法的前面
- sql - 如何在 SAP HANA Scalar User Defined Functions (UDF) 中编写 SQL 语句?
- android - 如何将权限 READ_PHONE_STATE 添加到 Android 仪器测试?
- typescript - 在 Typescript 中,如何将泛型容器类型的对象合并到对象类型的泛型容器中?
- css - Algolia 水平显示菜单