2016-12-09 2 views
5

Как я должен вставлять свой MyDbContext в свой уровень сервиса базы данных MyService?Внедрение DbContext в сервисный уровень

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; 
     } 
    } 
} 

В моем GetUser метод, я знаю, что я должен использовать мой впрыскивается MyDbContext здесь, но я не совсем уверен, как взять ее. Какую часть головоломки мне не хватает?

ответ

11

Вам не обязательно включать dbcontext самостоятельно, служба впрыска зависимой службы ASP.NET сделает это за вас.

Вы только декларировать свои услуги и свой контекст базы данных в классе запуска, и поставить DbContext вам нужно в конструкторе вашего сервиса:

Startup.cs (ваш должны выбрать срок службы вы хотите, здесь это Scoped обслуживание, один раз по запросу):

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

Ваш класс обслуживания:

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); 
} 

в контроллере, вы должны объявить т он службы (или контексту базы данных), нужно использовать таким же образом:

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 
     } 
} 

Примечания о контроллере: вы не должен добавить их в классе запуска, как вы делаете с вашим контекстом базы данных или вашим Сервисы. Просто реализуйте их конструктор.

Если Вам необходима дополнительная информация о инъекции depencency .NET ядра, официальная документация ясна и очень полная: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection


NB: В startup.cs, линия AddScoped является вариант. Вы можете выбрать срок службы, который вы хотите для своего обслуживания. Существует разные времена жизни вы можете выбрать:

Переходные

Переходные услуги прижизненные создаются каждый раз, когда они запрашиваются. Эта пожизненная работа лучше всего подходит для облегченных, безгосударственных услуг.

Scoped

услуги прижизненные Scoped создаются один раз для каждого запроса.

Singleton

прижизненные Singleton сервисы созданы в первый раз они просили (или когда ConfigureServices запускается, если указать экземпляр там), а затем каждый последующий запрос будет использовать тот же экземпляр.

Выше взяты из: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection


Примечание: Это не вопрос здесь, но ваш запрос данных GetUser выглядит немного странно для меня. Если ваша цель count() == 1 заключается в проверке единства пользователя, хорошим способом является добавление ограничения целостности в вашей базе данных. Если count() == 1 цель - проверить, что у вас есть данные, чтобы исключить исключение ссылки на объект null, вы можете использовать .FirstOrDefault(), он будет управлять этим для вас. Вы можете упростить этот метод:

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

Всегда указывайте прямые кавычки туда, откуда они пришли, чтобы избежать плагизма. Также форматируйте кавычки как «кавычки», чтобы было очевидно, что вы цитируете внешний источник. – Liam

+0

@Liam. Я не знал, как процитировать некоторый текст, я искал об этом. Это одна из причин, по которой я установил прямую ссылку на официальную документацию. Я искал, как это сделать, когда вы обновляете мой ответ;) – AdrienTorris

+0

Не беспокойтесь, просто хотел подчеркнуть это на самом деле. Хороший ответ – Liam

Смежные вопросы