1

컨테이너에 단일 구성 요소 인스턴스를 등록하려는 시나리오가 있지만, 불행하게도 응용 프로그램 시작시 생성 할 수 없습니다. 이 구성 요소는 응용 프로그램 수명주기 후에 조금만 사용할 수있는 일부 개체를 전달할 때만 인스턴스화 될 수 있습니다 (단, 다른 IoC 등록 서비스는 아닙니다) [아래 참고 사항].초기 구성 후 IoC 컨테이너에 등록

  • 후 IoC 컨테이너 에서 (응용 프로그램 시작에서 실행) 초기 구성 나쁜 관행을 구성 요소를 등록 있나요?
  • 직접 컨테이너를 참조하지 않고이를 수행하는 방법은 무엇입니까? 등록 서비스를 추상화해야합니까?
  • 시나리오를 지원하는 더 나은 방법이 있습니까? 실제 시나리오
    내가 UI 컨트롤의 특정 인스턴스로 초기화되는 용기에 넣고 싶은 구성 요소에 대한

참고 따라서 I가 있고, (그것은 기본적으로 어댑터입니다) 수동으로 구성 요소 인스턴스를 만들어 컨테이너에 등록합니다.
응용 프로그램 시작시이 작업을 수행했지만 불행히도 UI 컨트롤 인스턴스를 아직 사용할 수 없으며 직접 만들 수도 없습니다.
나중에도 구체적인 클래스를 모른 채 다른 구성 요소의 표면에서 UI 컨트롤 인스턴스에 연결할 수 없습니다.
이런 이유로 UI 컨트롤을 소유하고있는 클래스에 어댑터 등록 책임을 둘 수 있다고 생각했습니다.

내 초기 시나리오 :

public interface IDockManager { ... } 
public class AcmeDockManagerAdapter : IDockManager { 
    public AcmeDockManager(DockControl control) { ... } 
    ... 
} 

public class ShellViewModel { ... } 
public class ShellView : Window { 
    internal DockControl theDockControl; 
} 

public class AnotherViewModel { 
    AnotherViewModel(IDockManager dockManager) { ... } 
} 

내가 함께 unconfortable 해요 솔루션 :

public class ShellView : Window { 
    internal DockControl theDockControl; 
    public ShellView() { 
     InitializeComponents(); 
     var dockManager = new AcmeDockManagerAdapter(theDockControl); 
     //registration in the container 
    } 
} 

답변

1

당신은 대신에 "게으른 래퍼"을 등록 할 수 있습니다. 이러한 래퍼는 동일한 인터페이스를 구현하며 즉시 인스턴스화 될 수 있지만 작업을 수행하는 실제 구성 요소의 생성을 내부적으로 연기합니다. ploeh의 예 (LazyOrderShipper 또는 LazyOrderShipper2)를보십시오.

편집 : 정확하게 이해하면보기를 MVVM 스타일의 뷰 모델에 연결하려고합니다. 나는 container가 viewmodel 구조를 처리하도록하지만, view 구조와 viewmodel 배선을 직접 처리하는 것을 선호한다.

var mainViewModel = container.Get<MainViewModel>(); 
var mainView = new MainView(mainViewModel); 
Application.Run(mainView); 

을 그리고 MainView 생성자 내부에서 나는 자신의 뷰 모델이 필요합니다 자식 컨트롤의 관리 걸릴 것 : 내 스타트 업 코드는 다음과 같이 woul 당신이 엄격하게 MVVM 접근 방식을 따르는 경우

public MainView(MainViewModel viewModel) 
    { 
     // link "subviews" to "subviewmodels" 
     this.SomeChildControl.ViewModel = viewModel.SomeChildViewModel; 

     // normal MVVM property wiring 
     viewModel.TitleChanged += delegate { this.Text = viewModel.Title; }; 
     ... 
    } 

을 컨테이너에 뷰를 등록 할 필요가 없습니다. "보기와 대화해야하는 것"은 정말 기본보기 모델과 대화해야합니다. (탭 인터페이스 또는 도킹 된 창 GUI에서 플러그 가능한보기를 허용하려는 경우 상황이 더 흥미로워 지지만 또 다른 이야기입니다.)

+0

이것은 매우 우아한 해결책입니다. 그러나 내 문제는 구성 요소 인스턴스화 비용과 관련이 없으며 일부 생성자 인수의 가용성과 관련이 있습니다. 실제 인스턴스 생성을 연기하기 위해서는 적어도 지연 래퍼가 필요한 인수를 검색하는 방법을 알고 있어야하며, 마침내 인스턴스를 만들 때가옵니다. 좀 더 자세하게 설명해 줬어야했는데 어쩌면 그렇게 할 수 있습니다. 당신의 도움을 주셔서 감사합니다. –

+0

죄송 합니다만, 질문은 뷰와 VM 사이의 배선과 관련이 없습니다 (이미 설치되어 있습니다). 문맥을 명확히하기 위해 필요한 실제 수업을 추가했습니다. 동적 추가를위한 정확한 목적을 위해 도킹 부분을 추상화하고 ShellVM에서 인터페이스를 분리합니다. 종속성 삽입을 단순화하기 위해 컨테이너에 도킹 서비스를 넣는 것이 좋겠지 만, 이미 컨테이너에 싱글 톤으로 등록 된 ShellVM에서 액세스 할 수 있습니다. –

1

질문을 이해하는 방법은 비교적 간단합니다. 외부에서 theDockControl을 제공하십시오. 자동 생성 된 WinForms/WPF/뭐든간에 - 쓰레기를 사용하는 것이 엉망이라고 알고 있습니다 만, 여기에는 아무런 해결책도 없습니다.

+0

내 불안의 요점이 있다고 생각합니다. 디자인 관점에서 볼 때 외부에서부터 어댑터와 창 모두에 동일한 컨트롤 인스턴스를 제공하는 것이 좋습니다. 그렇게 간단합니다! 그것은 다른 이유로 어색 할 수도 있지만 또 다른 문제입니다. 지연 등록이 분쟁을 넘어서는 것 같아요. 도움을 주셔서 대단히 감사합니다. –

+0

걱정할 필요가 없습니다. 다음 번에 배지를 받게됩니다 :) –

관련 문제