2015-01-08 2 views
0

MVVM 응용 프로그램에서 작업하고 있습니다. 그것은 전체 응용 프로그램이 필요로하는 (단일 인스턴스) 객체와 특정 윈도우/컨트롤 만 필요한 일부 객체 (컨트롤 당 하나의 인스턴스)를 가지고 있습니다.StructureMap 컨테이너의 복제본 만들기

보통과 같이 모든 Application 인스턴스를 포함하도록 StructureMap 컨테이너를 구성하고 싶습니다. 창/컨트롤을 열면 컨테이너의 복제본을 만들고 해당 컨트롤에 필요한 객체를 복제본의 구성에 추가하려고합니다. 복제본은 원래 컨테이너를 확장해야하며 동일한 구성과 인스턴스를 포함해야합니다.

StructureMap과 관련이 있습니까? (나는 중첩 된 컨테이너를보고 있지만, 내가 원하는 것은 확실하지 않다.)

자세한 내용 ...

여기에 동작을 표시하는 테스트입니다. 먼저 표준 항목 :

[Test] 
public void Mupp() 
{ 
    var parent = new Container(x => 
     { 
      x.For<IMyServiceAgent>().Singleton().Use<MyServiceAgent>(); 
     }); 
    var parentServiceAgent = parent.GetInstance<IMyServiceAgent>(); 

그런 다음 복제본을 만듭니다. 부모와 같은 경우가 있습니다. (그것은 내가 찾는 방법 CreateCloneOf()의 구현입니다.)

IContainer scoped1 = CreateCloneOf(parent); 
    scoped1.GetInstance<IMyServiceAgent>().ShouldBeTheSameAs(parentServiceAgent); 

나는 내 로컬 객체와 구성을 확장하고 싶습니다. 제 클론과 인스턴스 (또는 구성)를 공유하지 않을 용기의 제 클론 생성

scoped1.Configure(x => 
     { 
      x.For<IMyPresenter>().Singleton().Use<MyPresenter>(); 
     }); 

    var scopedPresenter1 = scoped1.GetInstance<IMyPresenter>(); 
    scoped1.GetInstance<IMyPresenter>().ShouldBeTheSameAs(scopedPresenter1); 

. 범위 지정된 conatiner 구성 무슨

IContainer scoped2 = CreateCloneOf(parent); 
    scoped2.Configure(x => 
     { 
      x.For<IMyPresenter>().Singleton().Use<MyPresenter>(); 
     }); 
    scoped2.GetInstance<IMyPresenter>().ShouldNotBeTheSameAs(scopedPresenter1); 

스코프 컨테이너에서 범위 컨테이너를 생성 할 수 있어야 부모 컨테이너

parent.GetInstance<IMyPresenter>(); // Should throw 

에 있으면 안됩니다.

IContainer moreScoped = CreateCloneOf(scoped1); 
    moreScoped.GetInstance<IMyPresenter>().ShouldBeTheSameAs(scopedPresenter1); 
} 
+0

가능한지 확실하지 않지만 그 점이 아닙니다. [응용 프로그램 작성] (http://blog.ploeh.dk/2011/07/28/CompositionRoot/)에는 응용 프로그램 전체에 대해 하나 이상의 컨테이너가 없어야합니다. 런타임에 클래스의 인스턴스가 필요한 경우 DI 컨테이너가 아닌 [Abstract Factory] (http://sourcemaking.com/design_patterns/abstract_factory)를 사용하여 템플릿을 만들어야합니다. – NightOwl888

+0

@ NightOwl888 웹 앱의 경우 동의합니다. 데스크톱 응용 프로그램에서 창/컨트롤은 자체 세계 일 수 있습니다. 나는 공장을 하나 (복합 컨트롤 당 하나) 사용했지만, 그 안에 모든 보일러 플레이트를 IoC 컨테이너로 대체 할 수 있기를 바랬다. 하지만 당신의 조언을 듣고 내가 할 수있는 일이 있는지 알아 봅니다. –

답변

2

질문에 의해 판단하면 중첩 된 컨테이너 인 것 같습니다.

중첩 된 컨테이너를 만들면 중첩 된 컨테이너를 만들 수 있습니다. 중첩 된 컨테이너는 수명이 짧은 작업에 적합한 컨테이너의 복사본이므로 중첩 된 컨테이너의 변경 내용은 복제 된 컨테이너에 반영되지 않습니다 (read more here). 당신이 중첩 된 컨테이너는 다음 중첩 된 컨테이너가 모듈에 필요한 새로운 작업에 대한 StructureMap 레지스트리를 추가 할 수 있습니다 일단

에 사용되는

을과 같이 :.

설정 :

public void ApplicationBootstrap() 
{ 
    IContainer container = StructureMapCoreSetup.Initialise(); 
    container.Configure(c => 
    { 
     c.IncludeRegistry<DefaultRegistry>(); 
    }); 
} 

사용법 :

public class ApplicationModule 
{ 
    public ApplicationModule(IContainer container) 
    { 
     childContainer = container.GetNestedContainer(); 
     childContainer.Configure(x => 
     { 
      x.AddRegistry<ModuleSpecificRegistry>(); 
     }); 
    } 
} 

중첩 된 컨테이너의 변경 사항은 중첩 된 컨테이너의 중첩 인스턴스를 만든 경우를 제외하고는 다른 컨테이너의 컨테이너에 반영되지 않으며 완료되면 컨테이너를 삭제할 수 있습니다.

바라건대 이것은 당신이 찾고있는 것이거나 적어도 당신을 올바른 방향으로 향하게합니다!

+1

좋은 답변이지만 중첩 된 컨테이너를 구성/사용하고 있다고 생각하지 않습니다. 그것은'var childContainer = container.GetNestedContainer(); childContainer.Configure (x => ...' – CSharper

+0

잘 찾아 냈습니다! 지적 해 주셔서 감사합니다. 내 대답을 업데이트했습니다. –