I don't understand the official documentation, at the paragraph about dependency injection.
They say I can use a controller (but from here I know I don't need it because I'm using Razor pages) or I can access directly to ServiceProvider:
using (var context = serviceProvider.GetService<BloggingContext>())
{
// do stuff
}
but how to retrieve the reference to the ServiceProvider in a generic C# class of my project?
I setup the services in 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();
}
EDIT
To further clarify my confusion, what I'm trying to do is to add/get data from a Worker class. Here I found an example how to do it:
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);
}
But I cannot use a constructor without the argument DbContext if I'm going to use dependency injection. On the other side, if I add the argument, I have to pass the right value when I call the constructor as in the above example - and this is the initial question.
EDIT2
I'm going to post a "complete" example. It's hard to me to understand, but I'm trying anyway:
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();
}
}
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?}");
});
}
}
}
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; }
}
}
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());
}
}
}
}
}
}
Of course isn't complete nor compilable, because there are a lot of other files in the project (even without my own specific application).