2011-06-10 7 views
2

내 코드에는 factory 클래스가 있고 구조체 호출은 마음에 들지 않습니다. 어떻게해야합니까?구조체 및 팩토리 클래스

class ManagerBaseFactory 
{ 
    public ManagerBase GetInstance(SomeEnum e) 
    { 
     Type t; 

     switch (e) 
     { 
      case SomeEnum.A: 
       t = typeof(Manager1); 
      case SomeEnum.B: 
       t = typeof(Manager2); 
      case SomeEnum.C: 
       t = typeof(Manager3); 
     } 
     return (ManagerBase)StructureMap.ObjectFactory.GetInstance(t); 
    } 
} 

답변

2

이런 식으로 구조 맵을 사용할 때 문제가 보이지 않습니다. 현재 솔루션에 대해 어떤 점이 마음에 들지 않습니까?

더 이상 공장이 필요없는 명명 된 인스턴스를 사용할 수 있습니다. structuremap link

public class ServicesRegistry : Registry 
{ 
    public ServicesRegistry() 
    { 
     For<ManagerBase>().Use<Manager1>().Named("A"); 
     For<ManagerBase>().Use<Manager2>().Named("B"); 
     For<ManagerBase>().Use<Manager3>().Named("C"); 
    } 
} 

당신보다 당신이 반대 어떤 부분이 명확하지

SomeEnum e = SomeEnum.A; 
ObjectFactory.GetNamedInstance<ManagerBase>(e.ToString()); 
+0

ManagerBaseFactory이 검증되지 않습니다. Main에서 Structermap에 대한 호출을 하나만하고 싶습니다. – Hans

+0

나는이 구성을 undestand 확신하지 않습니다. 프로세서는 어떻게 생겼습니까? – Hans

+0

이것은 구조 매뉴얼에서 가져온 예제이며 프로세서는 중요하지 않습니다. 이 점은 구조지도를 사용하여 개체의 특정 인스턴스 (관리자 이름 인 ManagerBase)를 열거 자 값이 될 수있는 이름으로 가져올 수 있습니다. 내가 생각한 구체적인 요구 사항에 맞게 예제를 업데이트했습니다. – llMll

0

를 호출하여 올바른 하나를 검색 할 수 있습니다. 한 가지 개선 사항은 ManagerBaseFactory이 을 생성자로 사용하는 것으로, 이는 ObjectFactory 정적 게이트웨이 대신 사용할 수 있습니다. 그런 다음 ManagerBaseFactory을 컨테이너에서 꺼낼 수 있으며 컨테이너는 공장에서 스스로 주입합니다. 공장은 정적 종속성없이 단위 테스트가 쉬울 것입니다. 당신이 제네릭을 활용할 수 있도록

또한 스위치에 직접 반환 문을 넣을 수 :

case SomeEnum.A: 
    return _container.GetInstance<Manager1>(); 
+0

Manager 컨테이너를 사용하므로 ManagerBaseFactory를 테스트 할 수 없습니다. – Hans

+0

절대적으로 테스트 가능합니다. 그래서 ObjectFactory를 사용하는 대신 IContainer를 도입 할 것을 제안했습니다. 테스트 할 때 컨테이너의 새 인스턴스를 만들고 테스트중인 시나리오에 필요한 최소 크기로로드 한 다음 ManagerBaseFactory에 전달합니다. 아니면 IContainer를 스텁링하십시오. –

2

을 당신이 절대적으로 당신의 ManagerBaseFactory 컨테이너를 사용하지 않으려면, 당신은 모든 액세스 권한을 부여 할 수 컨테이너의 ManagerBase 구현 중 하나를 반환하고 올바른 값을 반환하도록합니다. StructureMap은 생성자에서 형식의 IEnumerable을 볼 때 해당 형식에 대해 알고있는 모든 인스턴스를 주입합니다.

class ManagerBaseFactory 
{ 
    private readonly IEnumerable<ManagerBase> _managers; 

    public ManagerBaseFactory(IEnumerable<ManagerBase> managers) 
    { 
     _managers = managers; 
    } 

    public ManagerBase GetInstance(SomeEnum e) 
    { 
     Type t; 

     switch (e) 
     { 
      case SomeEnum.A: 
       t = typeof(Manager1); 
       break; 
      case SomeEnum.B: 
       t = typeof(Manager2); 
       break; 
      case SomeEnum.C: 
       t = typeof(Manager3); 
       break; 
      default: 
       return null; 
     } 
     return _managers.FirstOrDefault(m => m.GetType().Equals(t)); 
    } 
} 

은 물론 당신은 반드시 당신의 ManagerBase 구현의 모든 컨테이너에로드되어 있는지 확인해야합니다

var container = new Container(x => 
{ 
    x.Scan(scan => 
    { 
     scan.TheCallingAssembly(); 
     scan.AddAllTypesOf<ManagerBase>(); 
    }); 
});