【问题标题】:Startup.Configure pattern for .Net Core Console App [closed].Net Core 控制台应用程序的 Startup.Configure 模式 [关闭]
【发布时间】:2021-05-14 07:12:58
【问题描述】:

我确定不是第一个遇到这种情况的人,但我找不到任何好的示例模式。在使用 .Net Core 3 和更新版本并创建 Web 应用程序时,我们可以使用 Startup 类

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Startup 类的一个很好的特性是它首先调用 ConfigureServices,我们可以在其中将东西添加到依赖注入容器中,然后调用支持依赖注入的 Configure 方法(我们可以向该方法添加参数以获取那些实例在 ConfigureServices 中向容器注册的类)。

这很好,因为它允许我们进行仅在实例化后可用的设置和初始化调用,并且如果被实例化的类具有一系列依赖关系,则可以节省大量代码。 Configure 方法允许基础架构链接那些我们必须在 ConfigureServices 方法中自己完成的依赖项。

在构建控制台应用程序时,我们没有 Startup 类的选项。我们直接调用ConfigureServices。

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureServices((hostContext, services) =>
        {
          ...
        })

哪里有一个干净的地方来做通常会考虑放在 Startup.Configure 方法中的工作?我对在托管服务启动之前放置您想要发生的事情特别感兴趣(例如,我有一个类响应需要连接订阅的数据库更改,我希望这发生在任何托管服务启动之前可能更改数据库)。所以换句话说,我正在寻找在托管服务启动之前利用依赖注入的机会。

【问题讨论】:

  • 构建主机和运行主机之间做任何你需要的工作。这也适用于网络应用程序,其中使用Configure 进行初始化工作并不是最好的方法。请参阅我的回答 here 的第二部分以了解我的意思,或参阅我的回答 here 了解扩展方法方法。
  • @KirkLarkin 扩展方法看起来很干净。我认为这是我将采用的模式。谢谢。

标签: c# asp.net-core .net-core


【解决方案1】:

在 cmets 中的 referenced answers 的基础上,我为 IHost 创建了扩展方法,它提供 DI 来替代不能在控制台应用程序中使用的 Startup.Configuration 方法。

public static class HostExtensions
{
    public static IHost PostBuildConfiguration(this IHost host, Action action)
    {
        action();
        return host;
    }

    public static IHost PostBuildConfiguration<T1>(this IHost host, Action<T1> action)
    {
        using (var scope = host.Services.CreateScope())
        {
            action(scope.ServiceProvider.GetRequiredService<T1>());
        }
        return host;
    }

    public static IHost PostBuildConfiguration<T1, T2>(this IHost host, Action<T1, T2> action)
    {
        using (var scope = host.Services.CreateScope())
        {
            action(scope.ServiceProvider.GetRequiredService<T1>(),
                scope.ServiceProvider.GetRequiredService<T2>());
        }
        return host;
    }

    public static IHost PostBuildConfiguration<T1, T2, T3>(this IHost host, Action<T1, T2, T3> action)
    {
        using (var scope = host.Services.CreateScope())
        {
            action(scope.ServiceProvider.GetRequiredService<T1>(),
                scope.ServiceProvider.GetRequiredService<T2>(),
                scope.ServiceProvider.GetRequiredService<T3>());
        }
        return host;
    }

    public static IHost PostBuildConfiguration<T1, T2, T3, T4>(this IHost host, Action<T1, T2, T3, T4> action)
    {
        using (var scope = host.Services.CreateScope())
        {
            action(scope.ServiceProvider.GetRequiredService<T1>(),
                scope.ServiceProvider.GetRequiredService<T2>(),
                scope.ServiceProvider.GetRequiredService<T3>(),
                scope.ServiceProvider.GetRequiredService<T4>());
        }
        return host;
    }
}

这可以在你的 main 中调用 Build 之后使用:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureServices((hostContext, services) =>
        {
          ...
        })
        .Build()
        .PostBuildConfiguration((Type1 a, Type2 b) => 
        {
           a.DoSomething();
           b.DoSomething();
        })
        .Run();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-02
    • 2023-04-10
    • 1970-01-01
    • 2018-04-11
    • 2016-12-07
    • 2015-09-21
    • 1970-01-01
    相关资源
    最近更新 更多