2014-11-11 1 views
2

내가 다음 클래스 구조를 가지고 있다고 가정 :이 다음과 같은 방법으로 쉽게 할 (내가 찾고 있어요 동작 설명,이 바보 같은 인위적인 예는 사실을 무시)를 할 수 있습니다 Autofac에서유니티 컨테이너에서 객체 스코프 싱글 톤을 얻는 방법?

public class Outer 
{ 
    [Dependency] 
    public Func<Inner> InnerFactory { get; set; } 
} 

public class Inner 
{ 
} 

:

[TestMethod] 
public void AutofacMakesThisEasy() 
{ 
    var builder = new ContainerBuilder(); 

    builder.RegisterType<Outer>().PropertiesAutowired(); 
    builder.RegisterType<Inner>().InstancePerOwned<Outer>(); 

    var container = builder.Build(); 

    var outer1 = container.Resolve<Owned<Outer>>().Value; 

    var inner1 = outer1.InnerFactory(); 
    var inner2 = outer1.InnerFactory(); 

    var outer2 = container.Resolve<Owned<Outer>>().Value; 

    var inner3 = outer2.InnerFactory(); 
    var inner4 = outer2.InnerFactory(); 

    Assert.AreNotSame(outer1, outer2, "outer1 == outer2"); 
    Assert.AreSame(inner1, inner2, "inner1 != inner2"); 
    Assert.AreNotSame(inner2, inner3, "inner2 == inner3"); 
    Assert.AreSame(inner3, inner4, "inner3 != inner4"); 
} 

다음 시험에 통과하기 위해 동일한 동작을 어떻게해야합니까?

[TestMethod] 
public void UnityHasMeScratchingMyHead() 
{ 
    var container = new UnityContainer(); 

    //// What shoud I do here? 

    var outer1 = container.Resolve<Outer>(); 

    var inner1 = outer1.InnerFactory(); 
    var inner2 = outer1.InnerFactory(); 

    var outer2 = container.Resolve<Outer>(); 

    var inner3 = outer2.InnerFactory(); 
    var inner4 = outer2.InnerFactory(); 

    Assert.AreNotSame(outer1, outer2, "outer1 == outer2"); 
    Assert.AreSame(inner1, inner2, "inner1 != inner2"); 
    Assert.AreNotSame(inner2, inner3, "inner2 == inner3"); 
    Assert.AreSame(inner3, inner4, "inner3 != inner4"); 
} 

참고 : 나는 사랑스러운 괜찮은 IOC의에 대한 유니티 도랑 싶지만, 그것은 매우 적극적인 판매 될 것입니다.

+0

왜 아래 표를 보냅니 까? 이것은 명확하게 표현 된 질문입니다. – briantyler

+0

[this] (http://msdn.microsoft.com/en-us/library/ff660895(v=pandp.20) .aspx) 및 [HierarchicalLifetimeManager] (http://msdn.microsoft.com/ en-us/library/microsoft.practices.unity.hierarchicallifetimemanager (v = pandp.51) .aspx)가 원하는 것일 수 있습니까? –

+0

2 개월 후 팔릴 수 있었고 우리는 Autofac으로 옮겨서 Caliburn을 기반으로하는 자체 MVVM 프레임 워크를 위해 프리즘을 버렸습니다. 모든 컨벤션 기반 바인딩은 없었습니다. (어떤 종류의 스케일에도 도달하면 실제로는 혼란 스럽습니다.). 그것은 우리를 위해 매우 잘되었습니다. 나는 철저히 비슷한 위치에있는 사람에게 똑같이하도록 권합니다. – briantyler

답변

2

InnerFactory 경우 당신은 당신이 조금 더 복잡 할 필요가 공장을 가지고 있기 때문에이 솔루션은 그러나 PerResolveLifetimeManager

[TestMethod] 
public void UnityHasMeScratchingMyHead() 
{ 
    var container = new UnityContainer(); 

    container.RegisterType<Inner>(new PerResolveLifetimeManager()); 

    var outer1 = container.Resolve<Outer>(); 
    //... and so on. 

것이다 단지 Inner 대신 Func<Inner>이었다. 공장에서 PerResolve를 만들고 나서 공장에서 동일한 인스턴스 (ContainerControlledLifetimeManager)를 생성해야합니다. 당신은 다음을 통해 그렇게 할 수 있습니다 :

[TestMethod] 
public void UnityHasMeScratchingMyHead() 
{ 
    var container = new UnityContainer(); 

    container.RegisterType<Func<Inner>>(new PerResolveLifetimeManager(), new InjectionFactory(x => 
    { 
     var child = x.CreateChildContainer(); 
     child.RegisterType<Inner>(new ContainerControlledLifetimeManager()); 
     return new Func<Inner>(() => child.Resolve<Inner>()); 
    })); 

    var outer1 = container.Resolve<Outer>(); 

    var inner1 = outer1.InnerFactory(); 
    var inner2 = outer1.InnerFactory(); 

    var outer2 = container.Resolve<Outer>(); 

    var inner3 = outer2.InnerFactory(); 
    var inner4 = outer2.InnerFactory(); 

    Assert.AreNotSame(outer1, outer2, "outer1 == outer2"); 
    Assert.AreSame(inner1, inner2, "inner1 != inner2"); 
    Assert.AreNotSame(inner2, inner3, "inner2 == inner3"); 
    Assert.AreSame(inner3, inner4, "inner3 != inner4"); 
} 

참고 사항 중 하나는 Unity is easily extensible입니다. 약간의 작업으로이 작업을 자주 수행하려는 경우 InstancePerOwnedLifetimeManager<T>을 만들고이를 사용하면 공장을 생성하는 것에 대해 걱정할 필요가 없습니다.

+0

Scott, 고마워. Autofac의 Owned <>를 복제하여 자식 컨테이너를 확인한 다음 모든 것을 HierarchicalLM에 등록합니다. 그것은 단지 내 목적에 충분하지만, 특정 부모 객체 유형으로 범위가 지정되지 않으므로 소유와 거의 같지 않습니다. 단지 새 하위 컨테이너를 투명하게 만듭니다. 나는 평생 매니저를 만들 때 찌르다가 인터페이스에 인터페이스가 없기 때문에 컨테이너에 연결하는 방법이 명확하지 않았습니다. 어떤 포인터? – briantyler

+0

@briantyler 불행히도 없습니다. 나는 그것을 할 수 있다는 것을 알고 있지만, 나는 그것을 스스로 해보려 고하지 않았다. –

+0

나는 (디 컴파일 된) 소스를 탐색 해왔고 이것이 어떻게 수행 될 수 있는지에 대한 아이디어를 얻기 시작했다. 일단 내가 금이 갔다면 다시보고 할거야. – briantyler

관련 문제