Deploying DbContext in the service layer

How should I embed my MyDbContext in the MyDbContext database service level?

Startup.cs

 public void ConfigureServices(IServiceCollection services) { services.AddDbContext<MyDbContext>(options => options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"])); services.AddMvc(); } 

MyDbContext.cs

 public partial class MyDbContext : DbContext { public virtual DbSet<User> User { get; set; } public MyDbContext(DbContextOptions<MyDbContext> options) :base(options) { } } 

appsettings.json

 { "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } }, "ConnectionStrings": { "DefaultConnection": "Server=MyServer;Database=MyDatabase;user id=MyUser;password=MyPassword;" } } 

MyService.cs

 public class MyService { public User GetUser(string username) { // Should i remove this call and get the reference from the injection somehow? MyDbContext db_context = new MyDbContext(optionsBuilder.Options); using (db_context) { var users = from u in db_context.User where u.WindowsLogin == username select u; if (users.Count() == 1) { return users.First(); } return null; } } } 

In my GetUser method GetUser I know that I should use my nested MyDbContext here, but I'm not quite sure how to get it. What part of the puzzle am I missing?

+5
source share
1 answer

You do not have to include dbcontext itself, for this you will need the ASP.NET kernel dependency injection service.

You should simply declare your services and your database context in your startup class and put the dbcontext services in your constructor:

Startup.cs (you need to choose the lifetime of the service you want, here it is a service with limited access, once per request):

 public void ConfigureServices(IServiceCollection services) { services.AddDbContext<MyDbContext>(options => options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"])); services.AddMvc(); services.AddScoped<IMyService, MyService>(); } 

Your class of service:

 public class MyService : IMyService { private readonly MyDbContext _context; public MyService(MyDbContext ctx){ _context = ctx; } public User GetUser(string username) { var users = from u in _context.User where u.WindowsLogin == username select u; if (users.Count() == 1) { return users.First(); } return null; } } public interface IMyService { User GetUser(string username); } 

In your controller, you need to declare the services (or database context) that you must use in the same way:

 public class TestController : Controller { private readonly IMyService _myService; public TestController(IMyService serv) { _myService = serv; } public IActionResult Test() { return _myService.MyMethod(); // No need to instanciate your service here } } 

Note about the controller: you do not need to add them to your launch class, as in the context of the database or your services. Just implement their constructor.

If you need more information about implementing the .NET Framework, the official documentation is clear and very complete: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection


Note: In startup.cs, the AddScoped line is an option. You can choose the service life you want for your service. There are different lifetimes that you can choose:

Transient

Temporary lifetime services are created each time they are requested. This lifelong job is best suited for lightweight, stateless services.

Scoped

Custom lifetime services are created once for each request.

Singleton

Singleton lifecycle services are created the first time they are (or when ConfigureServices starts if you specify an instance there), and then each subsequent request will use the same instance.

Above taken from: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection


Note. This is not a question, and your GetUser data request seems a little strange to me. If your goal of count () == 1 is to verify user unity, a good way is to add integrity constraints to your database. If count () == 1 goal is to verify that you have data to exclude null object reference exception, you can use .FirstOrDefault (), it will manage this for you. You can simplify this method:

 public User GetUser(string username) => (from u in _context.User where u.WindowsLogin == username select u).FirstOrDefault(); 
+12
source

Source: https://habr.com/ru/post/1261040/


All Articles