dependency-injection - 具有多个端点和依赖项注入(inject)的 Service Fabric

标签 dependency-injection autofac azure-service-fabric

我目前正在从事一个 POC 项目,我正在尝试弄清楚如何在不同端点之间共享服务依赖性以控​​制应用程序状态并处理所有服务请求(我们称之为 ControlService)——特别是当其中一个这些端点是 KestrelCommunicationListener/HttpSysCommunicationListener 并与 FabricTransportServiceRemotingListener(或任何其他类型的自定义监听器)结合

Autofac看起来很有希望,但是这些示例没有显示当容器是在启动而不是主入口点构建时如何让 HTTP 监听器工作——我是否需要将容器传递给 MyFabricService 以便它可以被传入和添加到启动注册?

我看到过使用 container.Update() 或使用 container.BeginLifetimeScope() 动态添加注册的引用资料,但它们都使用在 main 中构建的容器,然后我不确定如何添加 API由 HTTP 监听器创建到原始容器。

我可能没有很好地解释它,所以总而言之,我希望有类似下面的服务,可以通过 n 接收通信。不同的端点 - 处理消息,然后通过 n 发送消息。客户端(又名其他服务端点)

Control Service Endpoints

enter image description here

很高兴澄清是否有任何不清楚的地方 - 甚至可能使用另一个创意图表 :)

更新:

来自 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")

       };

服务副本监听器

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?}");
        //});

    }
}

所有服务依赖项都使用 startup.cs 中的 Microsoft.Extensions.DependencyInjection(不是 autofac)添加到 CompositionModules 中

这很好用并创建了我的 HTTP 监听器 - 我现在只需要一种方法来访问在我的 HTTP 监听器/网络主机启动期间添加到容器中的服务。

最佳答案

您可以使用 Autofac.Integration.ServiceFabriс,这是一个支持 Service Fabric 的 Autofac 扩展。你需要在 Program.cs 中创建一个容器

var builder = new ContainerBuilder();

builder.RegisterServiceFabricSupport();
builder.RegisterType<SomeService>().As<IManagementService>();

builder.RegisterStatelessService<ManagementService>("ManagementServiceType");
using (builder.Build())
{
   // Prevents this host process from terminating so services keep running.
   Thread.Sleep(Timeout.Infinite);
}

然后你可以将它注入(inject)到你的结构服务的构造函数中。您可以在 https://alexmg.com/posts/introducing-the-autofac-integration-for-service-fabric 上找到有关此主题的更多信息。

关于dependency-injection - 具有多个端点和依赖项注入(inject)的 Service Fabric,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50798531/

相关文章:

.net - 现实生活与SOLID开发一起工作

dependency-injection - Angular 2 - 没有服务提供者

c# - 如何在 Azure Service Fabric 应用程序中注入(inject) IHttpClientFactory?

c# - 注册 Moq 实例时 Autofac 抛出 File Not Found 异常

Autofac PropertiesAutowired - 是否可以忽略一个或多个属性?

azure - Azure Service Fabric 中的应用程序设计

javascript - typescript 中的 Angular2 DI。我们可以在 node.js/non-angular 项目中使用它吗?

c# - 简单注入(inject)器 - RegisterCollection 和 RegisterDecorator 使用 Composite 模式和接口(interface)继承

service - Microsoft Service Fabric 主机服务 (FabricHostSvc) 从未启动

azure - 在哪里设置和访问服务结构每个环境的运行时配置参数?