【问题标题】:How to use .NET Core's Built in Dependency Injection with Service Fabric如何在 Service Fabric 中使用 .NET Core 的内置依赖注入
【发布时间】:2019-07-08 19:30:53
【问题描述】:

下午好,

我最近开始尝试使用 Service Fabric 和 .NET Core。 我创建了一个无状态 Web API 并使用以下方法执行了一些 DI:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    var connString = Configuration.GetConnectionString("DefaultConnection");
    services.AddScoped<FaxLogic>();
    services.AddDbContext<ApplicationContext>(options => options.UseSqlServer(connString));
}

通过以上,我可以在我的 FaxLogic 类以及我的 DbContext 类上使用构造函数注入(通过 FaxLogic):

private readonly FaxLogic _faxLogic;
public FaxController(
    FaxLogic faxLogic)
{
    _faxLogic = faxLogic;
}
private readonly ApplicationContext _context;
public FaxLogic(ApplicationContext context)
{
    _context = context;
}

然后我创建了一个非 Web API 无状态服务。我希望能够像在我的 WebAPI 中一样访问我的 FaxLogic 和 DbContext,但在无状态服务的 RunAsync 方法中:

protected override async Task RunAsync(CancellationToken cancellationToken)
{
    // TODO: Replace the following sample code with your own logic 
    //       or remove this RunAsync override if it's not needed in your service.

    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();

        ServiceEventSource.Current.ServiceMessage(this.Context, "Hello!");

        // do db stuff here!

        await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
    }
}

我想知道我会怎么做。我尝试使用 CreateServiceInstanceListeners() 方法和使用 ServiceRuntime 注册的 Program.cs 文件,但我似乎无法弄清楚!任何帮助将不胜感激。

【问题讨论】:

标签: c# .net-core azure-service-fabric


【解决方案1】:

这里已经回答了解决方案:Set up Dependency Injection on Service Fabric using default ASP.NET Core DI container

总而言之,您必须在创建无状态服务的新实例之前注册依赖关系,然后创建工厂方法来解决依赖关系:

即:

public static class Program
{
    public static void Main(string[] args)
    {
        var provider = new ServiceCollection()
                    .AddLogging()
                    .AddSingleton<IFooService, FooService>()
                    .AddSingleton<IMonitor, MyMonitor>()
                    .BuildServiceProvider();

        ServiceRuntime.RegisterServiceAsync("MyServiceType",
            context => new MyService(context, provider.GetService<IMonitor>());
        }).GetAwaiter().GetResult();

有关详细信息,请参阅链接的答案。

【讨论】:

  • 你好迭戈!谢谢你的回答!在 API 的 Startup.cs 文件中,我可以访问 IConfiguration 接口以从加载的 AppSettings.json 中获取连接字符串。如果我想要 .AddDbContext,我将如何为 Program.cs 中的 DbContext 做类似的事情?
  • 啊,没关系,我已经解决了这个问题。抱歉,我看的不够仔细,有点困惑。感谢您的所有帮助!
  • @Diego Mendes 我对你的回答有点困惑。提供者不应该注册所有 DI,然后将其传递给 Service 类吗?在您的 sn-p 中,您为什么要传递 provider.GetService 而不仅仅是进程。在这种情况下,IFooService 会发生什么?
  • 这只是一个例子,你将传递你的服务需要的任何依赖。如果你愿意,你可以将提供者传递给服务,服务解决它自己的依赖关系。链接的答案包含模式信息。
【解决方案2】:

泰西,

我认为您正在寻找的内容已在我正在进行的项目中实现 - CoherentSolutions.Extensions.Hosting.ServiceFabric

CoherentSolutions.Extensions.Hosting.ServiceFabric 而言,您正在寻找的内容如下:

private static void Main(string[] args)
{
  new HostBuilder()
    .DefineStatelessService(
      serviceBuilder => {
        serviceBuilder
          .UseServiceType("ServiceName")
          .DefineDelegate(
            delegateBuilder => {
              delegateBuilder.ConfigureDependencies(
                dependencies => {
                  dependencies.AddScoped<FaxLogic>();
                });
              delegateBuilder.UseDelegate(
                async (StatelessServiceContext context, FaxLogic faxLogic) => {
                  while (true) {
                    cancellationToken.ThrowIfCancellationRequested();

                    ServiceEventSource.Current.ServiceMessage(context, "Hello!");

                    await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
                });
            })
       })
    .Build()
    .Run();
}

如果您有更多问题,请随时提问或查看项目wiki

希望对你有帮助。

【讨论】:

  • Oleg,感谢您的回复,但 Diego 已经为我解决了这个问题。不过我还是会看看你的项目,它看起来非常有用和有趣!
猜你喜欢
  • 2019-06-08
  • 2022-01-24
  • 2019-03-14
  • 2020-04-17
  • 1970-01-01
  • 2016-05-22
  • 1970-01-01
  • 2021-07-15
  • 2016-02-16
相关资源
最近更新 更多