C# 了解控制台应用程序中的.net核心依赖项注入
控制台应用程序不像web应用程序那样将启动文件用于配置服务,我正在努力理解依赖注入的关键概念 (请注意,以下示例未编译) 以下是我认为它应该如何工作的一个基本示例(请指出任何非常规或错误): 理解双语境C# 了解控制台应用程序中的.net核心依赖项注入,c#,asp.net-core,dependency-injection,C#,Asp.net Core,Dependency Injection,控制台应用程序不像web应用程序那样将启动文件用于配置服务,我正在努力理解依赖注入的关键概念 (请注意,以下示例未编译) 以下是我认为它应该如何工作的一个基本示例(请指出任何非常规或错误): 理解双语境 public class UnderstandingDIContext : DbContext { public UnderstandingDIContext(DbContextOptions<UnderstandingDIContext> optio
public class UnderstandingDIContext : DbContext
{
public UnderstandingDIContext(DbContextOptions<UnderstandingDIContext> options)
: base(options)
{ }
public DbSet<UnderstandingDIModel> UnderstandingDITable { get; set; }
}
公共类理解DiContext:DbContext
{
公共理解双上下文(DbContextOptions)
:基本(选项)
{ }
公共数据库集可理解可编辑{get;set;}
}
此代码的问题如下所示:
Worker()希望传递ILogger和IConfiguration参数,但我认为依赖项注入应该包括这一点
我无法运行“dotnet ef migrations add Initial”,因为我没有正确传递连接字符串(错误:“无法创建“UnderstandingDIContext”类型的对象”。)
“using(var context=new-constandingdicontext())”不会编译,因为我误解了DbContext位
我搜索了很多关于网络应用的例子,但是很少有关于控制台应用的例子。我完全误解了依赖项注入的整个概念吗?在使用构造函数注入时,依赖项只有在您创建的对象实际上是通过依赖项注入本身创建的情况下才能得到解决。因此,使依赖项注入在
Worker
中工作的关键是通过依赖项注入容器实际解析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");
不要自己创建
newworker()
。相反,在您的servicecolection
中注册它,并让DI为您实例化它。这是否意味着您必须实现一个接口(例如IWorker),或者这是一种推荐做法?不,您可以注册一个不带接口的依赖项。在注册调用和构造函数参数中都添加了具体类型。经过更多的研究,尝试了不同的方法,并在上面的评论中得到@Dai的建议的帮助,我几乎就到了那里,非常接近您发布的代码,但这一点解释和演示得很好,所以您得到了提示。非常感谢您抽出时间。在尝试创建数据库迁移时,我遇到一个错误“无法创建“UnderstandingDIContext”类型的对象”-所有内容都已正确编译,连接字符串正在成功读取。我错过了一些简单的东西吗?我觉得这与Sqlite中的Database.ensurereate()有关,但不确定该放在哪里。@mwade您是如何尝试创建数据库迁移的?您可能需要设置以使用EF工具。请使用CLI命令“dotnet EF migrations add Create”。为什么这样不行services.AddDbContext(options=>options.UseSqlite(builder.GetConnectionString(“DefaultConnection”))
使用时似乎没有正确注入:公共理解DiContext(DbContextOptions):base(options){}
我能找到的唯一方法是在OnConfiguring方法上手动输入连接字符串,而不是从appsettings.json获取。
public class UnderstandingDIContext : DbContext
{
public UnderstandingDIContext(DbContextOptions<UnderstandingDIContext> options)
: base(options)
{ }
public DbSet<UnderstandingDIModel> UnderstandingDITable { get; set; }
}
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();
}
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();
}
}