在不使用ASP.NET Core的情况下实现.NET Core中的DI

10
我想使用.NET Core编写一个守护进程,类似于cron job,并在一定时间间隔内协调API/DB调用。因此,它不需要暴露任何Web路由,因此不需要ASP.NET Core。
然而,据我所知,ASP.NET Core是您可以获得带有所有DI管道和基于环境的配置的好的Startup类的地方。
在我看来,我有两个选择:
1. 放弃ASP.NET Core,自己连接DI框架。如果我走这条路,我该怎么做?
2. 仅为DI部分包括ASP.NET Core,但如何生成“永远运行”的后台任务,而不在任何请求上下文之外?我的理解是,DI框架非常假设有某种传入请求来协调所有注入。

选项3. 使用Pure DI - Steven
1
DI 不需要 ASP.NET。启动不是必需的,它只是一种约定。您可以直接使用 Microsoft.Extensions.DependencyInjection.* 包。 - Panagiotis Kanavos
2个回答

10

你好像提出了多个问题,让我逐一回答吧。

无需启动类的依赖注入。

这绝对是可能的。由于 Startup 类是 WebHostBuilder 包(包含 Kestrel/webserver)的一部分。而 依赖注入 nuget 包 只是该包的一个依赖项,因此可以单独使用,方式如下:

var services = new ServiceCollection();
services.AddTransient<IMyInterface, MyClass>();
var serviceProvider = services.BuildServiceProvider(); //ioc container
serviceProvider.GetService<IMyInterface>();

在您的程序主函数(启动函数)中,您可以添加以下代码,并使ServiceProvider静态可用。
请注意,IHostingEnvironment也是kestrel包的一部分,不可用于您,但对此有简单的解决方法。
注册
我不确定您具体指的是什么意思,可以使用TaskCreationOptions.LongRunning在dotnet中生成任务,告诉调度程序您的任务将运行很长时间,dotnet可以为此优化线程。您还可以在这些任务中使用serviceProvider。
DI的唯一缺点是需要在应用程序启动时设置它,并且不能在运行应用程序时添加新服务(实际上可以添加到服务中,然后重新构建serviceProvider,但使用另一个外部IOC容器更容易)。如果您想运行某种插件系统,在其中依赖关系将自动注册,最好自己制作工厂方法。
另请注意,在使用插件时,当它们作为dll加载时,它们无法卸载,因此如果您有理论上无限数量的插件,则每次添加新插件时内存都会慢慢增加。

2
DI 的唯一缺点是您需要在应用程序启动时设置它,而无法在运行应用程序时添加新服务。我认为这根本不是缺点,因为 Register-Resolve-Register 是一种反模式 - Steven
@Steven 是的,我理解了,但我是在针对这个特定情况陈述。我明白具有作用域注册的危险性。它仍然是一个可能使用的功能,但你必须理解其中的危险(并且只有在你确实知道自己在做什么时才使用它)。 - Joel Harkes
1
我完全没有提到作用域的概念。我所指的是在运行应用程序时添加“新服务”的概念,这是您绝对不应该做的事情。尽管.NET Core DI不允许在运行时更新容器,但作用域注册的概念是它支持的。这两件事是无关的。 - Steven
ServiceCollection没有AddSingleton的定义,因此您需要添加NuGet包,该包引入了这些附加扩展。 - Joe Phillips

7
从.NET Core 2.1开始,应该使用通用主机来完成此操作。根据.NET Core文档所述:“通用主机的目标是将HTTP管道与Web Host API解耦,以实现更广泛的主机场景...”请访问以下链接了解更多信息:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.1
public static async Task Main(string[] args)
{
  var builder = new HostBuilder()
    .ConfigureAppConfiguration((hostingContext, config) =>

    .ConfigureServices((hostContext, services) =>
    {
       // ...
    });

  await builder.RunConsoleAsync();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接