3

둘 다 .NET Core 2.0을 대상으로하는 두 개의 Project, ProductStore.Web 및 ProductStore.Data 프로젝트가있는 C# 솔루션이 있습니다.DbContext MVC 프로젝트 외부의 종속성 삽입

다음과 같이 내 HomeController 및 CustomerRepository이 (내가 속도에 대한 HomeController에서 그것을 설정 한 고객 창조는 고객 컨트롤러,하지만 아직 발판 에드 그것을됩니다) :

namespace ProductStore.Web.Controllers 
{ 
    public class HomeController : Controller 
    { 
     private readonly DatabaseContext _context; 

     public HomeController(DatabaseContext context) 
     { 
      _context = context; 
     } 
     public IActionResult Index() 
     { 
      ICustomerRepository<Customer> cr = new CustomerRepository(_context); 
      Customer customer = new Customer 
      { 
       // customer details 
      }; 
      //_context.Customers.Add(customer); 
      int result = cr.Create(customer).Result; 
      return View(); 
     } 
    } 
} 

namespace ProductStore.Data 
{ 
    public class CustomerRepository : ICustomerRepository<Customer> 
    { 
     DatabaseContext _context; 
     public CustomerRepository(DatabaseContext context) 
     { 
      _context = context; 
     } 
    } 
} 

종속성 삽입은 _context를 컨트롤러 내부에서 자동으로 해결합니다. 그런 다음 컨텍스트를 ProductStore.Data에있는 CustomerRepository의 매개 변수로 전달합니다.

내 질문에 두 배입니다 : 나는 방법과 유사한 방법으로 IServiceCollection services를 통해 컨텍스트에 액세스 할 수 있습니다

  1. 이 (CustomerRepository에 컨트롤러에서 컨텍스트를 전달)이 가장 좋은 방법
  2. 하지 않는 것이 좋습니다 실행하는 경우에인가 DatabaseContext는 내 응용 프로그램 StartUp.cs 클래스의 서비스에 삽입됩니다.

컨텍스트를 전달할 필요가 없어야한다고 생각합니다. CustomerRepository가 컨텍스트를 가져와야합니다. 엔티티 프레임 워크 및 의존성 주입에 새로운 상대적으로 MVC 새로운 브랜드 참고

,

감사

+0

왜'context'를'repository'에 직접 삽입하지 않습니까? –

+0

@RubenVardanyan thats 내가 묻는 것. 저장소 내에서 새로운 컨텍스트 개체를 만들 수는 있지만 컨텍스트가 이미 내 응용 프로그램 서비스 내에있는 경우 다시 사용해야한다고 생각합니까? – Dave0504

+0

아래의 대답을 참조하십시오. –

답변

3

저장소 내부 서비스에 context 등록을 사용할 수 있도록 당신은 controllercontext을 통과 할 필요가 없습니다 . 내가 그렇게하는 것을 선호하는 방식은 다음과 같다. contextrepository에 넣은 다음 repository을 컨트롤러에 주입하십시오. 때 DependencyResolver 시도 그가 보는 HomeController에 주입하는 ICustomerRepository를 해결하기 위해 닷넷 코어 것이이 후이

// Service registrations in Startup class 
public void ConfigureServices(IServiceCollection services) 
{ 
    // Also other service registrations 
    services.AddMvc(); 
    services.AddScoped<DatabaseContext, DatabaseContext>(); 
    services.AddScoped<ICustomerRepository<Customer>, CustomerRepository>(); 
} 

// Controller 
namespace ProductStore.Web.Controllers 
{ 
    public class HomeController : Controller 
    { 
     private readonly ICustomerRepository _customerRepository; 

     public HomeController(ICustomerRepository customerRepository) 
     { 
      _customerRepository = customerRepository; 
     } 
     public IActionResult Index() 
     { 
      Customer customer = new Customer 
      { 
       // customer details 
      }; 
      //_context.Customers.Add(customer); 
      int result = _customerRepository.Create(customer).Result; 
      return View(); 
     } 
    } 
} 

//Repository 
namespace ProductStore.Data 
{ 
    public class CustomerRepository : ICustomerRepository<Customer> 
    { 
     DatabaseContext _context; 
     public CustomerRepository(DatabaseContext context) 
     { 
      _context = context; 
     } 
    } 
} 

모양을의 Microsoft 의존성 삽입 (Dependency Injection) 확장을 사용하여 우리의 경우 CustomerRepository에서 ICustomerRepository의 등록 구현 ()은 ConfigureServices 충족에 당신이 당신의 저장소를 정의하면 DatabaseContext에 대해 등록 서비스를받을 수 및 CustomerRepository

+1

코드 예제가 제네릭 클래스 – Yaser

+0

에 적합하지 않습니다. @ 예을 들어, 제네릭의 일부를 놓쳤습니다. 그러나이 경우 인터페이스는 일반적인 것이지 구현이 아닙니다. 따라서이 접근 방식이 효과적입니다. –

+0

그것은 나를 믿지 않을 것입니다.> 컴파일 오류 – Yaser

3

에 주입하기 위해 노력 매개 변수로 DatabaseContextDependencyResolver을 필요로 하나의 생성자가 HOD, 당신이 컨트롤러에 DbContext을 주입 할 필요가 없습니다, 단지 저장소 :

public class HomeController : Controller 
 
{ 
 
    private readonly ICustomerRepository _customerRepository; 
 

 
    public HomeController(ICustomerRepository customerRepository) 
 
    { 
 
     _customerRepository = customerRepository; 
 
    } 
 
    ... 
 
}
:

public void ConfigureServices(IServiceCollection services) 
 
{ 
 
    services.AddDbContext<DbContext>(options => 
 
     options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 
 
     
 
    services.AddScoped(typeof(ICustomerRepository<>), typeof(CustomerRepository<>)); 
 
}

그런 다음 당신은 단순히 컨트롤러에 저장소를 삽입 할 수

의존성 인젝터는 ca DbContext을 저장소에 주입하십시오.

1

1.(컨트롤러에서 CustomerRepository로 컨텍스트 전달)

"작업 단위 (Unit of Work)"패턴과 같은 것을 찾고 있다고 생각합니다.

Microsoft는 here을 만드는 방법에 대한 자습서를 작성했습니다.

컨텍스트 대신 컨트롤러에 저장소를 삽입 할 수도 있습니다.

2.하지 모범 사례, 난합니다 ... DatabaseContext 내 응용 프로그램의 StartUp.cs 클래스에 서비스에 삽입하는 방법과 유사한 방법으로 IServiceCollection 서비스를 통해 컨텍스트에 액세스 할 수 있습니다

내가 올바르게 이해한다면, 가능합니다. 또한 컨트롤러에 을 사용할 수 있도록 StartUp.cs의 서비스에 CustomerRepository를 추가하십시오.

Mabye this Microsoft의 튜토리얼도 도움이됩니다.