2009-09-26 4 views
11

나는 Niggddinner 및 ContactManager와 같은 더 간단한 응용 프로그램뿐만 아니라 Kigg와 같은 더 복잡한 응용 프로그램을 살펴 보았습니다. 나는 더 간단한 것들을 이해하고 더 복잡한 것들을 이해하고 싶습니다.다음 레벨로 MVC 가져 오기 : DI 및 작업 단위

일반적으로 간단한 응용 프로그램에는 LINQtoSQL 또는 Entity Framework의 맨 위에 저장소 클래스와 인터페이스가 있습니다 (느슨하게 결합되어있는 것처럼). 리포지토리는 컨트롤러에서 호출되어 필요한 데이터 작업을 수행합니다.

내가 Kigg 또는 Oxite 같은 더 복잡한 응용 프로그램을 검사 할 때 내가 볼 하나 개의 일반적인 패턴의 도입이다 (나는 단지 여기에 표면을 긁는하고 있지만 어딘가에 시작해야)

: Kigg의에서 (

  • IOC DI를 일
  • 의 경우 유니티)
  • 웹 요청 평생 관리자
  • 단위 여기

내 질문은 :

정말 느슨하게 결합 된 응용 프로그램을 사용하려면 Unity와 같은 것을 사용해야한다는 것을 알고 있습니다. 하지만 Unity에게 Web Request Lifetime Manager를 소개해야하는 순간도 있습니다. 왜 그런가요? Nerddinner와 같은 샘플 응용 프로그램에 Web Request Lifetime Manager가없는 이유는 무엇입니까? 그것은 정확히 무엇을합니까? 그것은 단결 특정한 것이냐?

두 번째 패턴은 작업 단위 (Unit of Work)의 소개입니다. 다시 한 번, 같은 질문 : Nerddinner 또는 ContactManager가 Unit of Work를 사용하지 않는 이유는 무엇입니까? 대신 이러한 응용 프로그램은 데이터 조작을 수행하기 위해 Linq2Sql 또는 Entity Framework 위에 저장소 클래스를 사용합니다. 작업 단위 (UOW)에 대한 표시가 없습니다. 정확히 무엇이며 사용해야하는 이유는 무엇입니까?

감사

다음

는 DinnersController 수준에서 Nerddiner에서 DI의 예입니다

public DinnersController() 
     : this(new DinnerRepository()) { 
    } 

    public DinnersController(IDinnerRepository repository) { 
     dinnerRepository = repository; 
    } 

그래서 내가 바로 때문에 첫 번째 생성자의 컨트롤러가 "소유"는 DinnerRepository하고 있다고 가정하는 생각이 따라서 거기에 선언 된 이후 컨트롤러의 수명에 의존 할 것인가?

답변

3

Linq-to-SQL을 직접 사용하면 컨트롤러가 데이터 컨텍스트에 대한 참조를 소유합니다 . 이것은 일반적으로 컨트롤러 내부의 개인 참조이므로, 구성의 일부로 생성됩니다. 한 곳에서 일하기 때문에 평생 관리 할 필요가 없습니다.

그러나 IoC 컨테이너를 사용하면 데이터 저장소가 컨트롤러 외부에서 만들어집니다. 생성 된 객체를 사용하는 방법과 기간을 모르는 IoC 컨테이너이므로 평생 전략이 도입됩니다.

예를 들어 데이터 컨텍스트 (리포지토리)는 일반적으로 웹 요청의 시작 부분에서 만들어지고 끝 부분에서 삭제됩니다. 그러나 외부 웹 서비스 또는 일부 정적 매퍼 (예 : 로거)에서 작동하는 구성 요소의 경우 매번 구성 요소를 만들 필요가 없습니다. 그래서 한 번만 (예 : 싱글 톤 라이프 스타일) 만들라고 말하고 싶을 수도 있습니다.

이 모든 일은 IoC 컨테이너 (Unity와 같은)가 많은 상황을 처리하도록 설계되어 있으며 사용자의 특정 요구를 모르기 때문에 발생합니다. 예를 들어, 일부 어플리케이션은 NHibernate (또는 Entity Framework)가 여러 페이지/웹 요청 동안 지속될 수있는 "대화"트랜잭션을 사용합니다. IoC 컨테이너를 사용하면 필요에 맞게 객체 수명을 조정할 수 있습니다. 그러나 이것은 가격이 책정 된 것과 마찬가지입니다. 미리 정의 된 전략이 없기 때문에 직접 선택해야합니다.

NerdDinner와 다른 응용 프로그램이 고급 기술을 사용하지 않는 이유는 단순히 다른 라이브러리의 고급 용도가 아닌 MVC 기능을 보여주기위한 것이기 때문입니다. 하나의 IoC 컨테이너 고급 기능을 시연하기 위해 작성된 기사를 기억합니다.이 기사는 우려 사항 분리와 같이 승인 된 디자인 패턴을 깨뜨 렸습니다.하지만 디자인 패턴이 기사의 목표가 아니기 때문에이 점이 중요하지 않았습니다. 단순한 MVC 데모 애플리케이션과 마찬가지로 MVC 신참 사용자가 IoC 미로에서 사라지는 것을 원하지 않습니다.

내가 설계 기준 예로서 Oxite보고 권하고 싶지 않다 : http://codebetter.com/blogs/karlseguin/archive/2008/12/15/oxite-oh-dear-lord-why.aspx http://ayende.com/Blog/archive/2008/12/19/oxite-open-exchangable-informative-troubled-engine.aspx

+0

감사합니다! 도움이되었습니다. 내 질문을 편집했습니다. 컨트롤러가 저장소/데이터 컨텍스트에 대한 참조를 소유하고 있다고 말할 때 이것이 무슨 뜻입니까? – Thomas

+0

정확하지 않습니다. NerdDinner에서는 단위 테스트를보다 쉽게하기 위해 IDinnerRepository를 수락하는 추가 생성자를 사용합니다. 하지만 네, 여전히 컨트롤러 (매개 변수없는 생성자)이거나 저장소 개체를 만들고 소유하는 테스트입니다. 둘 다 죽고 다른 저장소 사용자는 없습니다. 그래서 일생은 간단합니다. 그런데 그런 기술은 나쁘다. 당신은 그것에 관하여 더 많은 것을 여기에서 읽을 수있다 : http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/07/03/how-not-to-do-dependency-injection-in-nerddinner.aspx (또한 "가난한 사람의 IoC"에 대한 Google). – queen3

+0

지미 보거 드 (Jimmy Bogard)가 "가난한 사람의 IoC"라는 뻔뻔스러운 사례에 대한 논쟁은 여기에서 매우 좋습니다. 의견도 좋습니다. 확실히 읽을만한 가치가 있습니다. –

0

대부분의 DI 컨테이너가 평생의 개념에 닿아 있지는 않지만 대부분은 그렇다고 생각합니다. 관련된 시나리오에 따라 컨테이너는 등록 된 구성 요소의 동일한 인스턴스를 항상 반환하는 반면, 다른 구성 요소의 경우 항상 새로운 인스턴스를 반환 할 수 있습니다. 대부분의 컨테이너를 사용하면 특정 컨텍스트 내에서 동일한 인스턴스를 반환하도록 지정할 수 있습니다.

잘 모름 (지금까지 Windsor 및 Autofac을 사용함) 웹 요청 평생 관리자가 단일 웹 요청의 수명 동안 동일한 인스턴스가 컨테이너에서 제공되는 평생 전략 구현이라고 의심하십시오. Windsor와 같은 용기에서 비슷한 전략을 찾을 수 있습니다.

마지막으로, 귀하가 단원을 언급하고 있다고 가정합니다. 작업 단위는 본질적으로 하나의 기본 비즈니스 트랜잭션으로 성공하거나 실패하기를 원하는 일련의 조치입니다. 보다 공식적인 설명은 Martin Fowler의 definition을 참조하십시오. 이는 도메인 기반 디자인의 맥락에서 더 많은 인기를 얻은 개념입니다. 작업 단위 (UOW)는 해당 트랜잭션에서 적용한 변경 사항을 추적하고, 시간이 맞으면 하나의 ACID 트랜잭션에서 이러한 변경 사항을 확약합니다. 예를 들어 NHibernate에서.세션은 Linq2SQL에서 컨텍스트 인 반면 작업 단위와 더 구체적으로 변경 추적의 개념을 지원합니다 ...