我目前正在构建一个服务器应用程序,该应用程序通过TCP传递自定义协议。该服务器应用程序当前使用Autofac进行依赖项注入。
不过,最近我在解决方案中添加了一个ASP.NET Core项目,以提供HTTP API来运行服务器应用程序,主要是为了提供管理Web应用程序。
Autofac为ASP.NET Core项目提供了集成,但是我很难弄清楚如何告诉ASP.NET Core服务配置使用已经构建的Autofac服务容器,以便TCP服务HTTP API可以从同一容器解析服务。
Autofac为此提供了文档:
protected function aggregate($request, $model, $function, $column = null, $dateColumn = null)
{
$query = $model instanceof Builder ? $model : (new $model)->newQuery();
$column = $column ?? $query->getModel()->getQualifiedKeyName();
$previousValue = with(clone $query)->whereBetween(
$dateColumn ?? $query->getModel()->getCreatedAtColumn(), $this->previousRange($request->range)
)->{$function}($column);
return $this->result(
with(clone $query)->whereBetween(
$dateColumn ?? $query->getModel()->getCreatedAtColumn(), $this->currentRange($request->range)
)->{$function}($column)
)->previous($previousValue);
}
该示例仅显示如何从头开始为ASP.NET Core应用程序构建完整的容器,但是现在如何重用现有容器。
在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 ━━━━┛
}
上使用ConfigureServices
方法在这里不起作用,因为该方法的返回类型为IWebHostBuilder
,所以我不能在那里返回void
这是我启动应用程序的方式:
AutofacServiceProvider
那么我该如何使用同一个容器来解析TCP服务器和HTTP API中的依赖关系?
谢谢!
答案 0 :(得分:0)
我相信您应该可以用Autofac容器替换默认的(内置)asp.net核心容器。在这种情况下,Startup.ConfigureServices必须返回IServiceProvider(而不是void)。
查看“默认服务容器替换”部分in this documentation. 相关部分位于页面末尾。您应该能够适应您的情况。
希望这对您有用。如果是这样,请将其标记为答案。
答案 1 :(得分:0)
您还可以尝试提供聚合的服务提供商,类似于此处提供的服务提供商(https://github.com/kephas-software/kephas/blob/master/src/Kephas.Composition.DependencyInjection/Composition/DependencyInjection/AggregatedServiceProvider.cs):
/// <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容器,但是,正如我所看到的,这对您来说不是问题。