2011-02-16 2 views
11

저는 Dependency Injection과 Play Framework를 매우 좋아합니다. 그러나이 두 가지가 어떻게 함께 악용 될 수 있는지 보지 못했습니다.Play Framework와 함께 Dependency Injection을 사용하는 사례 사용

스프링과 Guice 용 모듈이 있지만 Play가 작동하는 방식으로 DI가 어떤 아주 간단한 경우를 넘어 DI가 어떻게 유익 할 수 있는지를 알 수 없습니다. 그래서에서 컨트롤러에 주입하는 PersonManager 필요가 없다

@Entity 
Person extends Model { 
    public static void delete(long id) { 
     em().find(id).remove(); 
    } 

    //etc 
} 

을 :

이의 좋은 예는 재생이 JPA 작업이 문제의 실체와 관련된 정적 메소드 수행 할 것으로 기대하고 있다는 것입니다 Spring J2EE 애플리케이션의 경우와 다를 바 없다. 대신 컨트롤러는 Person.delete(x)을 호출합니다.

분명히 DI는 외부 시스템과의 인터페이스가있는 경우에 유용합니다. 구체적인 구현은 테스트 등을 위해 조롱 될 수 있기 때문에 분명하지만 자체 내장 된 Play 애플리케이션에는별로 도움이되지 않습니다.

누구에게도 좋은 예가 있습니까? 누구든지 Manager 스타일 클래스를 Controller에 삽입하여 동일한 트랜잭션 내에서 많은 작업을 수행 할 수 있습니까?

+0

안녕하세요, DI _use 사례 _을 지정하는 제목을 편집했습니다.이 질문은 "DI를 Play와 함께 사용하는 방법"을 묻지 않기 때문에 오히려 언제입니까? 나는 아직도 Guice Module이 나를 위해 잘 작동하지 않는 방법을 찾고있다. – ripper234

답변

5

입니다 같은 트랜잭션 내에서 여러 작업을 수행 할 수 있도록 컨트롤러에 추가 할 수 있습니까? "

DI 질문에 대답하기 전에 나는 무엇인가를 알아 두어야합니다 : 트랜잭션은 Play에 의해 자동으로 관리됩니다. model documentation을 확인하면 요청이 시작될 때 트랜잭션이 자동으로 생성되고 마지막에 커밋됨을 알 수 있습니다. JPA를 통해 다시 롤백하거나 예외가 발생하면 롤백합니다.

나는이 사실을 알고 있는지 당신의 문장의 말씨로 확신 할 수 없기 때문에 이것을 언급합니다.

이제 DI 자체에, DI 내 (그리 광범위하지 않음) 경험에서, 나는 주로 사용되는 본 적이 :

  • 로드 ORM (최대 절전 모드) 공장/관리자

물론 서비스 클래스/DAO를 다른 클래스에로드하십시오. 그러나 더 많은 시나리오가 있지만 실제 사용법의 대부분을 다루고있을 것입니다. 이제 :

  • 첫 번째는 주로 컨트롤러에서 정적 메서드 작업을 자동으로
  • 두 번째도 상당히 관계가 당신이 당신의 JPA 객체 및 트랜잭션에 대한 액세스를 얻을으로 재생하려면 무관하다. 인스턴스화해야 할 도우미 클래스가있을 수 있으며 일부는 계층 구조 (공용 인터페이스)에 속해 DI가 유용 할 수도 있습니다. 하지만 당신은 원 공장 클래스를 만들고 DI의 항아리를 제거 할 수 있습니다.

여기에도 고려해야 할 사항이 있습니다. 저는 Guice에 대해 잘 모르겠지만 Spring은 DI 일뿐만 아니라 DI 모듈에 의존하는 많은 추가 기능을 제공합니다. 따라서 Play에서 DI를 사용하고 싶지는 않지만 Spring 도구를 활용하려면 간접적으로 (XML 구성을 통해) DI를 사용합니다.

1

실제로 이점이있는 경우에만 종속성 삽입을 사용해야 함을 다시 보여줍니다. 복잡한 서비스를 사용하면 유용하지만 대부분의 경우 그렇지 않습니다. play-documentation에있는 모델에 대한 장을 읽으십시오.

따라서 DI를 게임과 함께 사용할 수있는 예를 들어 보겠습니다. 아마도 복잡한 계산을해야하거나 보고서 엔진을 사용하여 pdf를 만들 수 있습니다. 나는 DI가 특히 테스트를 위해 유용 할 수 있다고 생각한다. 저 시스 모듈과 스프링 모듈이 유용하고 도움이 될 것 같습니다.

닐스

2

DI 플레이에서 ... 당신의 손에 당신이 그것을 가지고해서 DI를 사용하지 마십시오 ... 모든 곳에서 사용하는 궁극적 인 해결책이 아니라, 당신이 DI는 컨트롤러를 개발 할 필요가 없습니다/모델 등 ...하지만 때로는 좋은 디자인이 될 수도 있습니다. IMO, 잘 알고있는 인터페이스를 갖춘 서비스가 있다면 사용할 수 있지만 Play 외부에서이 서비스를 개발하고 게임 외부에서 테스트하고 게임을 테스트 해보고 싶습니다. 전체 서비스 구현에 의존하지 않기 위해 단지 더미 서비스를 사용하는 프로젝트. 따라서 DI는 재미있을 수 있습니다. 서비스를 느슨하게 사용하면됩니다.

"사람이 좋은 사례가 있습니까 사람이 관리자 스타일 클래스를 주입하는 데 사용합니까? 사실, 이것은 AFAIK DI 원래 사용 사례 ... 난 당신이 쓴이 문장에서 생각

+1

내가 할 수 있기 때문에 DI를 사용하려고하지 않는다. Play에서 DI가 어떻게 사용될 수 있는지 보려고했습니다. 그렇지 않으면 Spring과 Guice 모듈이 작성되지 않았을 것이 분명하지만, 원래의 질문에서 말했듯이, Play가 작동하는 방식은 DI를 사용하기 어렵고 아마도 불필요한 것으로 보입니다. – Rich

+0

나는 일반적으로 DI에 관하여 당신과 동의합니다 ... 그것은 많은 사람들이 잘 맞지 않아도 어디서나 DI를 사용하는 경향이 있다는 것을 알았습니다. 우리는 항상 똑같은 것을 알고 있습니다 : 우리는 뭔가 영리한 것을 발견하고 그것을 사방에 사용하고 싶습니다만, 특별한 경우에는 의미가 없습니다.) ... 최대 절전 모드는 똑같습니다 ... WebServices 또한 ... 모든 곳의 XML ... 지금 REST everywhere ... JSON 등 ... 어쨌든, Play + DI를 사용하는 것을 막을 수있는 방법이 없다고 생각합니다. Play는 단지 상태 유지가 아니라 DI이기 때문에 의미가 없습니다. – mandubian

2

방금 ​​Google Guice로 Play Framework 응용 프로그램을 설정하는 블로그 게시물을 작성했습니다. http://geeks.aretotally.in/dependency-injection-with-play-framework-and-google-guice

특히 응용 프로그램의 구성 요소가 특정 컨텍스트 또는 이와 유사한 다른 동작을 필요로 할 때 어떤 이점이 있습니다. 그러나 나는 사람들이 DI 문맥에 들어가는 것에 대해 선택적이어야한다고 믿는다.

+4

Google에서 귀하의 웹 사이트에 악성 코드가 있다고 말합니다. ? –

5

Play의 정적 초기화 접근에 대한 저의 겸허 한 의견에있는 문제! 테스트가 더 어렵게 만드는 것입니다. HTTP 메시지 데이터 (요청 및 응답)를 전달하는 정적 멤버 및 객체에 대해 HTTP와 객체 오리 엔테이션 문제에 접근하면 객체를 나머지 객체와 느슨하게 결합하는 기능으로 각 요청에 대한 새 인스턴스를 생성해야하는 번거 로움을 피할 수 있습니다 귀하의 프로젝트 수업 중.

다른 디자인의 좋은 예가 servlets이며 기본 클래스도 확장되지만 단일 인스턴스 작성 (기본값 : because there are configurations that enable more instances)으로 문제에 접근합니다.

아마도 두 가지 방법을 혼합하면 각 컨트롤러의 싱글 톤이 전체 정적 클래스의 동일한 특성을 제공하고 일부 종류의 개체의 종속성 주입을 허용하는 것이 더 좋을 것이라고 생각합니다. 그러나 요청이나 세션 범위가있는 객체는 컨트롤러가 새로운 요청이있을 때마다 만들어야합니다. 또한 의존성 주입 제어를 반전시킴으로써 테스트 가능성을 향상시켜 임의의 주입 점을 허용합니다.

의존성은 컨테이너 또는 테스트에 의해 주입 될 수 있습니다. 아마도 이전에 이미 테스트되었을 것 같은 무거운 물건에 대한 모의 (mock)를 사용합니다.

FunctionalTest을 확장하면 응용 프로그램 서버가 시작되어 저장소, 서비스, 크롤러, http 클라이언트 등과 같은 무거운 객체의 가격을 지불하므로이 정적 모델은 개발자를 테스트 컨트롤러에서 멀어지게합니다. 일부 코드가 컨트롤러에서 실행되었는지 확인하기 위해 많은 오브젝트를 부트 스트랩하기를 기다리고 싶습니다. 개발자가 프로그래밍 보조자/가이드로서 그들을 좋아하도록 테스트가 빠르고 명확해야합니다.

+0

필자는 "컨트롤러가 요청이있을 때마다 요청이나 세션 범위가있는 객체는 생각하지 않았습니다."라고 어떻게 생각하십니까? 이는 주어진 요청에 대해 설정 될 수있는 편리한 객체를 통해 허용 될 수 있으며 이러한 객체는 요청/세션 데이터를 전달하지만 이러한 객체가 인스턴스 변수에 설정되면 동시성과 동기화의 모든 문제가 발생하므로이 가격이 감소하게됩니다 경합 때문에 전체 처리량. 사용자 당 컨트롤러 인스턴스를 갖는 것이 더 좋을까요? –

관련 문제