В настоящее время я работаю над проектом POC и пытаюсь выяснить, как я могу разделить зависимость службы между различными конечными точками, чтобы контролировать состояние приложения и обрабатывать все запросы на обслуживание (давайте назовем его ControlService) - особенно когда один изэти конечные точки являются KestrelCommunicationListener / HttpSysCommunicationListener и объединяются с FabricTransportServiceRemotingListener (или любым другим типом настраиваемого прослушивателя)
Autofac выглядел многообещающе, но примеры не показывают, как заставить работать прослушиватель HTTPкогда контейнер встроен в автозагрузку, а не в основную точку входа - нужно ли передавать контейнер в MyFabricService, чтобы его можно было передавать и добавлять при регистрации запуска?
Я видел ссылки на использованиеcontainer.Update () или добавление регистраций на лету с помощью container.BeginLifetimeScope (), но все они используют контейнер, встроенный в main, и тогда я не уверен, как добавить API-интерфейсы, созданные слушателем HTTP.r к исходному контейнеру.
Возможно, я не очень хорошо это объясняю, поэтому в заключение я хотел бы найти что-то похожее на приведенный ниже сервис, который может принимать сообщения через nразные конечные точки - обработать сообщение и затем отправить сообщения через n.клиенты (или другие конечные точки обслуживания)
![Control Service Endpoints](https://i.stack.imgur.com/33iAc.png)
![enter image description here](https://i.stack.imgur.com/bC92j.png)
С удовольствием уточню, если что-то неясно- возможно, даже используя другую креативную диаграмму:)
Обновлено:
Из Program.Main ()
ServiceRuntime.RegisterServiceAsync("ManagementServiceType",
context => new ManagementService(context)).GetAwaiter().GetResult();
Вот мой сервис Fabric
public ManagementService(StatefulServiceContext context)
: base(context)
{
//this does not work but is pretty much what I'm after
_managementService = ServiceProviderFactory.ServiceProvider.GetService(typeof(IManagementService)) as IManagementService;
}
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() =>
new ServiceReplicaListener[]
{
//create external http listener
ServiceReplicaListenerFactory.CreateExternalListener(typeof(Startup), StateManager, (serviceContext, message) => ServiceEventSource.Current.ServiceMessage(serviceContext, message), "ServiceEndpoint"),
//create remoting listener with injected dependency
ServiceReplicaListenerFactory.CreateServiceReplicaListenerFor(() => new RemotingListenerService(_managementService), "ManagmentServiceRemotingEndpoint", "ManagementServiceListener")
};
ServiceReplicaListener
public static ServiceReplicaListener CreateExternalListener(Type startupType, IReliableStateManager stateManager, Action<StatefulServiceContext, string> loggingCallback, string endpointname)
{
return new ServiceReplicaListener(serviceContext =>
{
return new KestrelCommunicationListener(serviceContext, endpointname, (url, listener) =>
{
loggingCallback(serviceContext, $"Starting Kestrel on {url}");
return new WebHostBuilder().UseKestrel()
.ConfigureServices((hostingContext, services) =>
{
services.AddSingleton(serviceContext);
services.AddSingleton(stateManager);
services.AddApplicationInsightsTelemetry(hostingContext.Configuration);
services.AddSingleton<ITelemetryInitializer>((serviceProvider) => new FabricTelemetryInitializer(serviceContext));
})
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddServiceFabricConfiguration(serviceContext);
})
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddDebug();
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseStartup(startupType)
.UseUrls(url)
.Build();
});
});
}
Запуск
public class Startup
{
private const string apiTitle = "Management Service API";
private const string apiVersion = "v1";
private readonly IConfiguration configuration;
public Startup(IConfiguration configuration)
{
this.configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
var modules = new List<ICompositionModule>
{
new Composition.CompositionModule(),
new BusinessCompositionModule()
};
foreach (var module in modules)
{
module.AddServices(services, configuration);
}
services.AddSwashbuckle(configuration, apiTitle, apiVersion, "ManagementService.xml");
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddApplicationInsights(app.ApplicationServices);
// app.UseAuthentication();
// app.UseSecurityContext();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
// app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseCors("CorsPolicy");
app.UseMvc();
app.UseSwagger(apiTitle, apiVersion);
//app.UseMvc(routes =>
//{
// routes.MapRoute(
// name: "default",
// template: "{controller=Home}/{action=Index}/{id?}");
//});
}
}
Все сервисные зависимости добавляются в модули CompositionModules с использованием Microsoft.Extensions.DependencyInjection (не autofac) в startup.cs
Это прекрасно работает и создает мой HTTP-прослушиватель - теперь мне просто нужен способ получить доступ к моим службам, которые были добавлены в контейнер во время запуска моего http listener / webhost.