2

this response과 함께 Mark Seemann's blog post을 참조하면이 코드를 참조하는 서비스 로케이터 패턴 오버플로를 클래스 생성자를 통해 사용하는 단점을 이해합니다. 나는 또한이 문제를 다루는 Dependency Injection with Ninject, MVC 3 and using the Service Locator Pattern을 읽었다. ASP.NET MVC의 서비스 위치 지정자

그러나, 내 질문이 특정 사건에 관한 : 여기

public class MyController 
{ 
    public void GetData() 
    { 
     using (var repository = new Repository()) 
     { 
      // Use the repository which disposes of an Entity Framework 
      // data context at the end of its life. 
     } 
    } 

    // Lots of other methods. 
} 

내가 자동으로 내부 엔티티 프레임 워크 데이터 컨텍스트를 인스턴스화 저장소를 호출하는 방법을 포함하는 컨트롤러를 가지고있다. 이 단일 데이터 컨텍스트는 컨텍스트가 리포지토리의 모든 메서드에서 호출되기 때문에 사용되므로 리포지토리 개체의 전체 수명 동안 단일 컨텍스트를 공유하는 것이 좋습니다.

컨트롤러 클래스가 크기 때문에이 저장소가 사용되지 않을 가능성이 더 큽니다. DC를 인스턴스화하는 것이 비용이 많이 드는 작업이라고 가정합니다 (아마도 잘못되었습니다). 그렇게하지 않는 것이 좋습니다. 서비스 로케이터 패턴을 사용하면 실제로 컨텍스트가 필요할 때까지 인스턴스 생성을 연기 할 수 있지만 위의 링크에서 유효한 인수가 있으면 인스턴스를 피하는 것이 좋습니다.

위와 같은 경우 의존성 삽입을 사용하는 것이 더 효율적인 방법이 있다면 내 저장소와 기본 데이터 컨텍스트를 불필요하게 인스턴스화하지 못하게하는 것입니다.

+0

이 질문은 너무 주관적입니다. "더 잘"은 매우 모호합니다. –

+0

나는 내가 묻고있는 것을 명확히하기 위해이 질문을 편집했다. –

답변

2

답변은 저장소가 연결을 관리하는 방식에 달려 있다고 생각합니다. 구성시 데이터베이스에 대한 연결을 열면 Dependency Injection이 아니라 저장소에 문제가 있다고 생각합니다. 리포지토리는 요청이있을 때만 연결을 열고 응답을 받자 마자 닫습니다. 이 패턴을 따르면, Dependency Injection은 여전히 ​​의미가 있습니다.


은 갱신을 바탕으로, 당신은 EF가 구축 될 때, 단지 요청이 데이터베이스에 대한 연결을 열 수 없기 때문에 DI를 사용하여 여전히 더 낫다. 데이터 컨텍스트가 작기 때문에 요청 당 컨텍스트를 만드는 데 필요한 오버 헤드가 적을만큼 가치가 있습니다.


하나 더 코멘트 : 당신은 또한 당신의 저장소로 데이터 컨텍스트를 주입하고 DI 컨테이너 컨텍스트의 수명을 제어시키는 것을 고려해야한다. 이렇게하면 단일 요청 중에 하나 이상의 리포지토리에서 동일한 컨텍스트를 사용할 수 있습니다. Here's a pretty good resource explaining how to implement the Repository and Unit of Work patterns with Entity Framework in ASP.NET MVC.

+0

저장소를 작성할 때이 점을 고려했지만 저장소의 모든 단일 메소드가 동일한 연결을 사용하므로 연결 수명을 저장소 인스턴스의 수명에 연결하는 것이 편리합니다. 이것을하지 않을 충분한 이유가 있습니까? –

+0

컨트롤러가 ASP.NET MVC에서 사용되는 경우 모든 요청이 새로운 컨트롤러, 즉 새로운 저장소와 새로운 연결을 인스턴스화하기 때문에 모든 메소드가 동일한 연결을 사용하지 않습니다. – sellmeadog

+0

귀하의 의견에 대한 답변으로 질문을 업데이트했습니다. –

2

컨트롤러 클래스가 크기 때문에 특정 구성에서 연결이 사용되지 않을 가능성이 더 큽니다. 따라서 리포지토리를 인스턴스화하고 표준 생성자를 사용하여 연결을 열지 않습니다. 기반 DI.

Lazy하는 Func, 또는 대신에 공장을 주입 :

public class MyController 
{ 
    // Use constructor injection to populate this. 
    private Func<MyRepository> _repository; 

    public void GetData() 
    { 
     using (var repository = _repository()) 
     { 
      // ... 
     } 
    } 
} 

당신은 당신이 그들을 필요로 할 때까지 실제 인스턴스를 생성 방지 할 수 있습니다 그 방법을.

@ sellmeadog의 답변도 좋습니다.

+0

저장소를 제어하지 못하는 경우이 방법을 사용하는 것이 좋습니다. – sellmeadog

1

리포지토리 생성자에 데이터베이스 연결을 삽입해야하는지 묻는 중입니다.추상 팩토리 실제 데이터베이스 연결 대신 팩토리을 삽입하는 디자인 패턴을 사용해 볼 수 있습니다.

public class MyController 
{ 
    public void GetData() 
    { 
     using (var repository = new Repository(IDatabaseConnectionFactory dbConnFac)) 
     { 
      // Use the repository which disposes of a database connection 
      // at the end of its life. 
     } 
    } 

    // Lots of other methods. 
} 

이렇게하면 저장소에서 데이터베이스 연결의 수명주기를 관리하는 동안 종속성 삽입의 이점을 얻을 수 있습니다.