C# 使用依赖项注入访问DbContext
我不理解官方关于依赖注入的段落 他们说我可以使用控制器(但我知道我不需要它,因为我使用的是Razor页面),或者我可以直接访问ServiceProvider:C# 使用依赖项注入访问DbContext,c#,asp.net-core,dependency-injection,asp.net-core-mvc,entity-framework-core,C#,Asp.net Core,Dependency Injection,Asp.net Core Mvc,Entity Framework Core,我不理解官方关于依赖注入的段落 他们说我可以使用控制器(但我知道我不需要它,因为我使用的是Razor页面),或者我可以直接访问ServiceProvider: using (var context = serviceProvider.GetService<BloggingContext>()) { // do stuff } 但是如果要使用依赖注入,我不能使用没有参数DbContext的构造函数。另一方面,如果我添加参数,我必须在调用构造函数时传递正确的值,如上面的示例所示——
using (var context = serviceProvider.GetService<BloggingContext>())
{
// do stuff
}
但是如果要使用依赖注入,我不能使用没有参数DbContext的构造函数。另一方面,如果我添加参数,我必须在调用构造函数时传递正确的值,如上面的示例所示——这是初始问题
编辑2
我将发布一个“完整”的示例。我很难理解,但我正在努力:
program.cs
using Hangfire;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Options;
namespace MyProject
{
public class Program
{
public static void Main(string[] args)
{
IWebHost host = BuildWebHost(args);
BackgroundJob.Enqueue<MyClass>(x => x.ImportOperatorList());
host.Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}
使用Hangfire;
使用Microsoft.AspNetCore;
使用Microsoft.AspNetCore.Hosting;
使用Microsoft.Extensions.Options;
名称空间MyProject
{
公共课程
{
公共静态void Main(字符串[]args)
{
IWebHost主机=BuildWebHost(args);
BackgroundJob.Enqueue(x=>x.ImportOperatorList());
host.Run();
}
公共静态IWebHost BuildWebHost(字符串[]args)=>
WebHost.CreateDefaultBuilder(args)
.UseStartup()
.Build();
}
}
startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Hangfire;
using MyProject.Models;
namespace MyProject
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyProjectContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyProjectContext")));
services.AddHangfire(options => options.UseSqlServerStorage(Configuration.GetConnectionString("MyProjectContext")));
services.AddOptions();
services.Configure<MySettings>(options => Configuration.GetSection("MySettings").Bind(options));
services.AddMvc().AddDataAnnotationsLocalization();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHangfireDashboard();
app.UseHangfireServer();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
}
}
}
使用Microsoft.AspNetCore.Builder;
使用Microsoft.AspNetCore.Hosting;
使用Microsoft.EntityFrameworkCore;
使用Microsoft.Extensions.Configuration;
使用Microsoft.Extensions.DependencyInjection;
使用壁炉;
使用MyProject.Models;
名称空间MyProject
{
公营创业
{
公共启动(IConfiguration配置)
{
配置=配置;
}
公共IConfiguration配置{get;}
//此方法由运行时调用。请使用此方法将服务添加到容器中。
public void配置服务(IServiceCollection服务)
{
services.AddDbContext(options=>options.UseSqlServer(Configuration.GetConnectionString(“MyProjectContext”));
services.AddHangfire(options=>options.UseSqlServerStorage(Configuration.GetConnectionString(“MyProjectContext”));
services.AddOptions();
services.Configure(options=>Configuration.GetSection(“MySettings”).Bind(options));
services.AddMvc().AddDataAnnotationsLocalization();
}
//此方法由运行时调用。请使用此方法配置HTTP请求管道。
公共无效配置(IApplicationBuilder应用程序,IHostingEnvironment环境)
{
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
其他的
{
app.UseExceptionHandler(“/Error”);
}
app.UseStaticFiles();
app.UseHangfireDashboard();
app.UseHangfireServer();
app.UseMvc(路由=>
{
routes.MapRoute(
名称:“默认”,
模板:“{controller}/{action=Index}/{id?}”);
});
}
}
}
MyProjectContext.cs
using Microsoft.EntityFrameworkCore;
namespace MyProject.Models
{
public class MyProjectContext : DbContext
{
public MyProjectContext(DbContextOptions<MyProjectContext> options) : base(options) { }
public DbSet<Operator> Operators { get; set; }
}
public class Operator
{
public int Id { get; set; }
[MaxLength(40)]
public string Name { get; set; }
public int Password { get; set; }
}
}
使用Microsoft.EntityFrameworkCore;
名称空间MyProject.Models
{
公共类MyProjectContext:DbContext
{
公共MyProjectContext(DbContextOptions选项):基本(选项){}
公共DbSet运算符{get;set;}
}
公共类运算符
{
公共int Id{get;set;}
[MaxLength(40)]
公共字符串名称{get;set;}
公共int密码{get;set;}
}
}
MyClass.cs
using MyProject.Models;
using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
namespace MyProject
{
public class MyClass
{
const string REGEX_OPERATORS = "^(?<Id>.{4})(?<Name>.{40})(?<Password>.{5})";
private readonly Regex reOperators = new Regex(REGEX_OPERATORS, RegexOptions.Compiled);
public void ImportOperatorList()
{
var path = @"F:\testdata.txt";
string[] lines = File.ReadAllLines(path);
foreach (var line in lines)
{
Match match = reOperators.Match(line);
if (match.Success)
{
string rawId = match.Groups["Id"].Value;
string rawName = match.Groups["Name"].Value;
string rawPassword = match.Groups["Password"].Value;
int Id;
try
{
Id = int.Parse(rawId, System.Globalization.NumberStyles.Integer);
}
catch (Exception)
{
throw;
}
string Name = rawName;
int Password;
try
{
Password = int.Parse(rawPassword, System.Globalization.NumberStyles.Integer);
}
catch (Exception)
{
throw;
}
using (var context = new MyProjectContext(/* ??? */))
{
var op = new Operator
{
Id = Id,
Name = Name,
Password = Password
};
context.Operators.Add(op);
Debug.WriteLine(context.SaveChanges());
}
}
}
}
}
}
使用MyProject.Models;
使用制度;
使用系统诊断;
使用System.IO;
使用System.Text.RegularExpressions;
名称空间MyProject
{
公共类MyClass
{
const string REGEX_操作符=“^(?{4})(?{40})(?{5})”;
private readonly Regex reOperators=new Regex(Regex_操作符,RegexOptions.Compiled);
公共无效导入运算符列表()
{
var path=@“F:\testdata.txt”;
string[]lines=File.ReadAllLines(路径);
foreach(行中的var行)
{
匹配=重新运算符。匹配(行);
如果(匹配成功)
{
字符串rawId=match.Groups[“Id”].Value;
字符串rawName=match.Groups[“Name”].Value;
字符串rawPassword=match.Groups[“Password”].Value;
int-Id;
尝试
{
Id=int.Parse(rawId,System.Globalization.NumberStyles.Integer);
}
捕获(例外)
{
投掷;
}
字符串名称=原始名称;
int密码;
尝试
{
Password=int.Parse(rawPassword,System.Globalization.NumberStyles.Integer);
}
捕获(例外)
{
投掷;
}
使用(var context=newmyprojectcontext(/*???*/))
{
var op=新运算符
{
Id=Id,
Name=Name,
密码=密码
};
context.Operators.Add(op);
Debug.WriteLine(context.SaveChanges());
}
}
}
}
}
}
当然,它既不完整也不可编译,因为项目中还有很多其他文件(即使没有我自己的特定应用程序)。您必须手动将上下文参数传递给函数,依赖项注入不能为您完成此操作。因此,在program.cs中,您可以添加:
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<MyProjectContext>();
// pass context to relevant Classes/Functions, i.e.
MyClass myClass = new MyClass();
myClass.ImportOperatorList(context);
}
建立在你的自我回答之上 重塑
using MyProject.Models;
using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
namespace MyProject
{
public class MyClass
{
const string REGEX_OPERATORS = "^(?<Id>.{4})(?<Name>.{40})(?<Password>.{5})";
private readonly Regex reOperators = new Regex(REGEX_OPERATORS, RegexOptions.Compiled);
public void ImportOperatorList()
{
var path = @"F:\testdata.txt";
string[] lines = File.ReadAllLines(path);
foreach (var line in lines)
{
Match match = reOperators.Match(line);
if (match.Success)
{
string rawId = match.Groups["Id"].Value;
string rawName = match.Groups["Name"].Value;
string rawPassword = match.Groups["Password"].Value;
int Id;
try
{
Id = int.Parse(rawId, System.Globalization.NumberStyles.Integer);
}
catch (Exception)
{
throw;
}
string Name = rawName;
int Password;
try
{
Password = int.Parse(rawPassword, System.Globalization.NumberStyles.Integer);
}
catch (Exception)
{
throw;
}
using (var context = new MyProjectContext(/* ??? */))
{
var op = new Operator
{
Id = Id,
Name = Name,
Password = Password
};
context.Operators.Add(op);
Debug.WriteLine(context.SaveChanges());
}
}
}
}
}
}
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<MyProjectContext>();
// pass context to relevant Classes/Functions, i.e.
MyClass myClass = new MyClass();
myClass.ImportOperatorList(context);
}
public void ImportOperatorList(MyProjectContext context)
{
// ...
context.Operators.Add(op);
context.SaveChanges();
}
public class MyClass {
const string REGEX_OPERATORS = "^(?<Id>.{4})(?<Name>.{40})(?<Password>.{5})";
private readonly Regex reOperators = new Regex(REGEX_OPERATORS, RegexOptions.Compiled);
private readonly IFileSystem File;
private readonly IProjectContext context;
public MyClass(IFileSystem File, IProjectContext context) {
this.File = File;
this.context = context;
}
public void ImportOperatorList() {
var path = @"F:\testdata.txt";
var lines = File.ReadAllLines(path);
foreach (var line in lines) {
var match = reOperators.Match(line);
if (match.Success) {
string rawId = match.Groups["Id"].Value;
string rawName = match.Groups["Name"].Value;
string rawPassword = match.Groups["Password"].Value;
var op = new Operator {
Id = int.Parse(rawId, System.Globalization.NumberStyles.Integer),
Name = rawName,
Password = int.Parse(rawPassword, System.Globalization.NumberStyles.Integer)
};
context.Operators.Add(op);
}
}
if (lines.Length > 0)
Debug.WriteLine(context.SaveChanges());
}
}
public interface IFileSystem {
string[] ReadAllLines(string path);
}
public class FileWrapper : IFileSystem {
public string[] ReadAllLines(string path) {
var lines = File.ReadAllLines(path);
return lines;
}
}
public interface IProjectContext : IDisposable {
DbSet<Operator> Operators { get; set; }
int SaveChanges();
//...add other functionality that needs to be exposed as needed
//eg: Database Database { get; }
//...
}
public class MyProjectContext : DbContext, IProjectContext {
public MyProjectContext(DbContextOptions<MyProjectContext> options) : base(options) { }
public DbSet<Operator> Operators { get; set; }
}
public void ConfigureServices(IServiceCollection services) {
services.AddDbContext<MyProjectContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyProjectContext")));
services.AddHangfire(options => options.UseSqlServerStorage(Configuration.GetConnectionString("MyProjectContext")));
services.AddOptions();
services.Configure<MySettings>(options => Configuration.GetSection("MySettings").Bind(options));
services.AddMvc().AddDataAnnotationsLocalization();
//...adding additional services
services.AddScoped<IProjectContext, MyProjectContext>();
services.AddTransient<IFileSystem, FileWrapper>();
services.AddTransient<MyClass, MyClass>();
}
using (var scope = host.Services.CreateScope()) {
var services = scope.ServiceProvider;
var myClass = services.GetRequiredService<MyClass>();
myClass.ImportOperatorList();
}