【问题标题】:Set up Dependency Injection on Service Fabric using default ASP.NET Core DI container使用默认 ASP.NET Core DI 容器在 Service Fabric 上设置依赖注入
【发布时间】:2019-06-08 16:20:20
【问题描述】:

我想使用 ASP.NET Core 的默认 DI 容器为我的 Service Fabric 项目设置 DI。

//This is what I've got so far, and it works great
ServiceRuntime.RegisterServiceAsync(
  "MyServiceType",
  context => new MyService(context, new MyMonitor()
).GetAwaiter().GetResult();

//This is how I use it
public MyService(StatefulServiceContext context, IMonitor myMonitor)
  : base(context)
{
  this._myMonitor = myMonitor;           
}

如果 MyMonitor 类依赖于 ConfigProvider 类,我将如何设置 DI,如下所示:

public MyMonitor(IConfigProvider configProvider)
{
  this._configProvider = configProvider;
}

【问题讨论】:

    标签: dependency-injection .net-core azure-service-fabric


    【解决方案1】:

    我想这个问题会给你一些启发:Why does ServiceRuntime.RegisterServiceAsync return before the serviceFactory func completes?

    从技术上讲,ServiceRuntime.RegisterServiceAsync() 是一个依赖注册,它需要你传递 serviceTypeName 和负责创建服务的工厂方法Func<StatelessServiceContext, StatelessService> serviceFactory

    工厂方法接收上下文并返回服务(有状态或无状态)。

    对于 DI,你应该提前注册所有依赖并调用解析服务来创建构造函数,比如:

    var provider = new ServiceCollection()
                .AddLogging()
                .AddSingleton<IFooService, FooService>()
                .AddSingleton<IMonitor, MyMonitor>()
                .BuildServiceProvider();
    
    ServiceRuntime.RegisterServiceAsync("MyServiceType",
        context => new MyService(context, provider.GetService<IMonitor>());
    }).GetAwaiter().GetResult();
    

    PS:

    • 永远不要在 DI 中注册上下文 (StatelessServiceContext\StatefulServiceContext),在共享进程方法中,多个分区可能托管在同一个进程上,并且会包含多个上下文。
    • 此代码 sn-p 未测试,我过去使用过,无法验证是否匹配相同的代码,但非常接近使用的方法,可能需要一些调整。

    【讨论】:

      【解决方案2】:

      嗨@OscarCabreraRodríguez

      我正在致力于简化 Service Fabric Reliable Services 开发的项目,它对依赖注入场景具有强大的内置支持。

      您可以找到一般信息project pagewiki 和有关依赖注入的具体信息here

      这个想法是项目将您从直接使用 Service 实例中抽象出来,而是为您提供一组更具体的对象。

      这是一个简单的 ASP.NET Core 应用示例:

      public static void Main(string[] args)
      {
        new HostBuilder()
          .DefineStatefulService(
            serviceBuilder =>
            {
              serviceBuilder
                .UseServiceType("ServiceType")
                .DefineAspNetCoreListener(
                  listenerBuilder =>
                  {
                    listenerBuilder
                      .UseEndpoint("ServiceEndpoint")
                      .UseUniqueServiceUrlIntegration()
                      .ConfigureWebHost(
                        webHostBuilder => 
                        { 
                          webHostBuilder
                            .ConfigureServices(
                              services =>
                              {
                                // You can configure as usual.
                                services.AddTransient<IMyService, MyService>();
                              })
                            .UseStartup<Startup>(); 
                        });
                  });
            })
            .Build()
            .Run();
      
      [Route("api")]
      public class ApiController : Controller
      {
        public ApiController(IMyService service) { }
      
        [HttpGet]
        [Route("value")]
        public string GetValue()
        {
          return $"Value from {nameof(ApiController)}";
        }
      }
      

      希望我正确理解您的用例,并且此信息是相关的。

      【讨论】:

      • 感谢@Oleg Karasik,但我更喜欢使用 Diego Mendes 的答案(如下),因为它更接近我所寻找的
      猜你喜欢
      • 2019-07-08
      • 2018-03-23
      • 1970-01-01
      • 1970-01-01
      • 2017-04-18
      • 2017-02-27
      • 2020-06-21
      • 2016-09-27
      • 2022-01-24
      相关资源
      最近更新 更多