- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
看不懂官方documentation ,在有关依赖注入(inject)的段落中。
他们说我可以使用 Controller (但来自 here 我知道我不需要它,因为我正在使用 Razor 页面)或者我可以直接访问 ServiceProvider:
using (var context = serviceProvider.GetService<BloggingContext>())
{
// do stuff
}
但是如何在我的项目的通用 C# 类中检索对 ServiceProvider 的引用?
我在 startup.cs 中设置服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyDbContext")));
services.AddHangfire(options => options.UseSqlServerStorage(Configuration.GetConnectionString("MyDbContext")));
services.AddOptions();
services.Configure<MySettings>(options => Configuration.GetSection("MySettings").Bind(options));
services.AddMvc().AddDataAnnotationsLocalization();
}
为了进一步澄清我的困惑,我正在尝试做的是从 Worker 类添加/获取数据。 Here我找到了一个如何做的例子:
using (var context = new BloggingContext())
{
var blog = new Blog { Url = "http://sample.com" };
context.Blogs.Add(blog);
context.SaveChanges();
Console.WriteLine(blog.BlogId + ": " + blog.Url);
}
但是如果我要使用依赖注入(inject),我不能使用没有参数 DbContext 的构造函数。另一方面,如果我添加参数,我必须在调用构造函数时传递正确的值,如上例所示 - 这是最初的问题。
我将发布一个“完整”示例。我很难理解,但我正在尝试:
程序.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();
}
}
启动.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?}");
});
}
}
}
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; }
}
}
我的类.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());
}
}
}
}
}
}
当然不是完整的也不是可编译的,因为项目中还有很多其他文件(即使没有我自己的特定应用程序)。
最佳答案
建立在你自己的答案之上。
重构 MyClass
以依赖于抽象而不是与具体紧密耦合。
这里是重构后的MyClass
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>();
}
现在,当使用作用域服务提供者时,您可以请求您的类,并且在解析 MyClass
时将注入(inject)所有依赖项
using (var scope = host.Services.CreateScope()) {
var services = scope.ServiceProvider;
var myClass = services.GetRequiredService<MyClass>();
myClass.ImportOperatorList();
}
由于上面的范围,当容器超出范围时,容器将管理容器创建的任何服务的处置。
关于c# - 使用依赖注入(inject)访问 DbContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47440794/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
PowerShell Web Access 允许您通过 Web 浏览器运行 PowerShell cmdlet。它显示了一个基于 Web 的控制台窗口。 有没有办法运行 cmdlet 而无需在控制台窗
我尝试在无需用户登录的情况下访问 Sharepoint 文件。 我可以通过以下任一方式获取访问 token 方法一: var client = new RestClient("https://logi
我目前正在尝试通过 Chrome 扩展程序访问 Google 服务。我的理解是,对于 JS 应用程序,Google 首选的身份验证机制是 OAuth。我的应用目前已成功通过 OAuth 向服务进行身份
假设我有纯抽象类 IHandler 和派生自它的类: class IHandler { public: virtual int process_input(char input) = 0; };
我有一个带有 ThymeLeaf 和 Dojo 的 Spring 应用程序,这给我带来了问题。当我从我的 HTML 文件中引用 CSS 文件时,它们在 Firebug 中显示为中止。但是,当我通过在地
这个问题已经有答案了: JavaScript property access: dot notation vs. brackets? (17 个回答) 已关闭 6 年前。 为什么这不起作用? func
我想将所有流量重定向到 https,只有 robot.txt 应该可以通过 http 访问。 是否可以为 robot.txt 文件创建异常(exception)? 我的 .htaccess 文件: R
我遇到了 LinkedIn OAuth2: "Unable to verify access token" 中描述的相同问题;但是,那里描述的解决方案并不能解决我的问题。 我能够成功请求访问 toke
问题 我有一个暴露给 *:8080 的 Docker 服务容器. 我无法通过 localhost:8080 访问容器. Chrome /curl无限期挂断。 但是如果我使用任何其他本地IP,我就可以访
我正在使用 Google 的 Oauth 2.0 来获取用户的 access_token,但我不知道如何将它与 imaplib 一起使用来访问收件箱。 最佳答案 下面是带有 oauth 2.0 的 I
我正在做 docker 入门指南:https://docs.docker.com/get-started/part3/#recap-and-cheat-sheet-optional docker-co
我正在尝试使用静态 IP 在 AKS 上创建一个 Web 应用程序,自然找到了一个带有 Nginx ingress controller in Azure's documentation 的解决方案。
这是我在名为 foo.js 的文件中的代码。 console.log('module.exports:', module.exports) console.log('module.id:', modu
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用 MGTwitterEngine"将 twitter 集成到我的应用程序中。它在 iOS 4.2 上运行良好。当我尝试从任何 iOS 5 设备访问 twitter 时,我遇到了身份验证 to
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用以下 API 列出我的 Facebook 好友。 https://graph.facebook.com/me/friends?access_token= ??? 我想知道访问 token 过
401 Unauthorized - Show headers - { "error": { "errors": [ { "domain": "global", "reas
我已经将我的 django 应用程序部署到 heroku 并使用 Amazon s3 存储桶存储静态文件,我发现从 s3 存储桶到 heroku 获取数据没有问题。但是,当我测试查看内容存储位置时,除
我是一名优秀的程序员,十分优秀!