gpt4 book ai didi

c# - 了解控制台应用程序中的 .net Core 依赖注入(inject)

转载 作者:行者123 更新时间:2023-12-05 03:01:18 25 4
gpt4 key购买 nike

控制台应用不像 Web 应用那样将启动文件与配置服务一起使用,我正在努力理解依赖注入(inject)的关键概念。

(请注意下面的例子不能编译)

这是我认为它应该如何工作的一个基本示例(请指出任何非常规或错误的地方):

        static void Main(string[] args)
{
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddUserSecrets<Settings>()
.Build();

var services = new ServiceCollection()
.AddLogging(b => b
.AddConsole())
.AddDbContext<UnderstandingDIContext>(options =>
options.UseSqlite(builder.GetConnectionString("DefaultConnection")))
.BuildServiceProvider();

var logger = services.GetService<ILoggerFactory>()
.CreateLogger<Program>();

logger.LogInformation("Starting Application");

var worker = new Worker();

logger.LogInformation("Closing Application");
}

但是我如何在“Worker”类中使用这些服务呢?:

        public Worker(ILogger logger, IConfiguration configuration)
{
logger.LogInformation("Inside Worker Class");
var settings = new Settings()
{
Secret1 = configuration["Settings:Secret1"],
Secret2 = configuration["Settings:Secret2"]
};
logger.LogInformation($"Secret 1 is '{settings.Secret1}'");
logger.LogInformation($"Secret 2 is '{settings.Secret2}'");

using (var context = new UnderstandingDIContext())
{
context.Add(new UnderstandingDIModel()
{
Message = "Adding a message to the database."
});
}
}

了解DIContext

    public class UnderstandingDIContext : DbContext
{
public UnderstandingDIContext(DbContextOptions<UnderstandingDIContext> options)
: base(options)
{ }

public DbSet<UnderstandingDIModel> UnderstandingDITable { get; set; }
}

这段代码存在的问题如下:

Worker() 期望传递 ILogger 和 IConfiguration 参数,但我认为依赖注入(inject)应该涵盖这些?

我无法运行“dotnet ef migrations add Initial”,因为我没有正确传递连接字符串(错误:“无法创建类型为‘UnderstandingDIContext’的对象。”)

'using (var context = new UnderstandingDIContext())' 不会编译,因为我误解了 DbContext 位。

我搜索了很多,有很多关于网络应用程序的例子,但很少有关于控制台应用程序的例子。我是不是完全误解了依赖注入(inject)的整个概念?

最佳答案

当使用构造函数注入(inject)时,只有当您创建的对象实际上是通过依赖注入(inject)本身创建时,才会解析依赖关系。因此,使依赖注入(inject)在您的 Worker 中工作的关键是通过依赖注入(inject)容器实际解析 Worker

这其实很简单:

var services = new ServiceCollection()
.AddLogging(b => b.AddConsole())
.AddDbContext<UnderstandingDIContext>(options =>
options.UseSqlite(builder.GetConnectionString("DefaultConnection")));

// register `Worker` in the service collection
services.AddTransient<Worker>();

// build the service provider
var serviceProvider = services.BuildServiceProvider();

// resolve a `Worker` from the service provider
var worker = serviceProvider.GetService<Worker>();

var logger = serviceProvider.GetService<ILogger<Program>>();
logger.LogInformation("Starting Application");

worker.Run();

logger.LogInformation("Closing Application");

此外,由于您使用的数据库上下文默认注册为范围 依赖项,因此我建议您也创建一个服务范围——或者更改数据库的生命周期注册时的上下文。

var serviceProvider = services.BuildServiceProvider();

using (var scope = serviceProvider.CreateScope())
{
var worker = serviceProvider.GetService<Worker>();
worker.Run();
}

请注意,我还在您的 worker 上创建了一个显式方法 Run,因此您没有构造函数中的逻辑。

public class Worker
{
private readonly ILogger<Worker> _logger = logger;
private readonly IConfiguration _configuration = configuration;
private readonly UnderstandingDIContext _dbContext = dbContext;

public Worker(ILogger<Worker> logger, IConfiguration configuration, UnderstandingDIContext dbContext)
{
_logger = logger;
_configuration = configuration;
_dbContext = dbContext;
}

public void Run()
{
_logger.LogInformation("Inside Worker Class");
var settings = new Settings()
{
Secret1 = configuration["Settings:Secret1"],
Secret2 = configuration["Settings:Secret2"]
};

_logger.LogInformation($"Secret 1 is '{settings.Secret1}'");
_logger.LogInformation($"Secret 2 is '{settings.Secret2}'");

_dbContext.Add(new UnderstandingDIModel()
{
Message = "Adding a message to the database."
});
_dbContext.SaveChanges();
}
}

关于c# - 了解控制台应用程序中的 .net Core 依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55983541/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com