Je travaille actuellement sur un projet POC et j'essaie de comprendre comment je peux partager une dépendance de service entre différents points d'extrémité pour contrôler l'état de l'application et gérer toutes les demandes de service (appelons-le ControlService) - spécifiquement lorsque l'un de ces points d'extrémité est un KestrelCommunicationListener / HttpSysCommunicationListener et combiné avec un FabricTransportServiceRemotingListener (ou tout autre type d'écouteur personnalisé).
Autofac semble prometteur mais les exemples ne montrent pas comment faire fonctionner un écouteur HTTP lorsque le conteneur est construit au démarrage plutôt qu'au point d'entrée principal. Devrais-je passer le conteneur à MyFabricService pour qu'il puisse être passé et ajouté par les enregistrements de démarrage ?
J'ai vu des références à l'utilisation de container.Update() ou à l'ajout d'enregistrements à la volée à l'aide de container.BeginLifetimeScope() mais elles utilisent toutes un conteneur construit en main et je ne sais pas comment ajouter les API créées par l'écouteur HTTP au conteneur original.
Je ne l'explique peut-être pas très bien, donc en résumé je cherche à avoir quelque chose comme le service ci-dessous qui peut recevoir des communications via n. points d'extrémité différents - traiter le message et ensuite envoyer des messages via n. clients (aka d'autres points d'extrémité du service)
Heureux de clarifier si quelque chose n'est pas clair - peut-être même en utilisant un autre diagramme créatif :)
Mis à jour :
De Programme.Main()
ServiceRuntime.RegisterServiceAsync("ManagementServiceType",
context => new ManagementService(context)).GetAwaiter().GetResult();
Voici mon service de tissus
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();
});
});
}
Démarrage
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?}");
//});
}
}
Toutes les dépendances du service sont ajoutées dans les CompositionModules en utilisant Microsoft.Extensions.DependencyInjection (pas autofac) dans startup.cs.
Cela fonctionne très bien et crée mon écouteur HTTP - j'ai maintenant besoin d'un moyen d'accéder à mes services qui ont été ajoutés au conteneur pendant le démarrage de mon écouteur http / webhost.