2010-06-27 5 views
4

Windsor IOC를 완전히 사용하기 위해 웹 응용 프로그램을 마이그레이션하기 시작했습니다. 내가 만나는 작은 문제가 여기있다.IOC를 사용하는 동안 정적 클래스를 처리하는 방법

나는이 좀 애플리케이션 레벨의 전역 값

EG (클래스의 단순화 된 버전)을 저장하는 데 사용되는 정적 클래스의 몇 :

public static class SiteInfo 
{ 
     public static Language Language = (Language)byte.Parse(SiteInfo.Val("language")); 
     public static string Code = Site.Code; 
     public static string Name = Site.Name; 

     public static SiteCachedData CachedData { get; set; } 
     public static Site Site { get; set; } 

     public static void Init() 
     { 
      //Get site info from DB here 
      //I need to inject _SiteRepository here but I can't 
      //since I don't have access to the constructor 
     } 
} 

내가 IOC에 새로운 오전과 내가 정적 클래스를 이해 예방을 권고 받았다. 이 상황을 처리하는 좋은 방법은 무엇입니까? 이것을 싱글 톤으로 바꾸려고 생각하고 있지만 그것이 최선의 선택인지 확신 할 수 없습니다.

답변

0

클래스의 단일 인스턴스를 컨테이너에 등록 할 수 있으므로 싱글 톤처럼 동작합니다. 컨테이너는 매번 동일한 인스턴스를 제공합니다.

3

이것은 정적 클래스를 피하는 이유 중 하나입니다. 컨트롤을 주입하거나 반전하기가 어렵습니다. 그들은 일반적으로 몇 가지 하위 수준 클래스의 친밀한 세부 사항을 알아야합니다. 클래스는 정적 클래스이므로 다른 클래스의 모든 클래스에서 이미 사용할 수 있고 삽입 할 필요가 없으므로 이탈 할 수 있습니다.

내가 한 한 가지 트릭은 정적 클래스에 위임 한 두 번째 클래스를 만드는 것입니다. 그런 다음 인터페이스를 새 클래스에 추가하고 IoC 프레임 워크를 쉽게 사용할 수 있습니다.

public static class StaticClass 
{ 
    public static object Method() 
} 

public class NonstaticClass : INewInterface 
{ 
    public object Method() 
    { 
     return StaticClass.Method(); 
    } 
} 

이 리팩터링의 좋은 점은 메서드로 메서드를 이동 한 다음 이동하면서 새로운 개체와 인터페이스를 결정할 수 있다는 것입니다. 결국 원래 정적 클래스를 제거 할 수 있습니다. 한 번에 하나의 인스턴스 만 존재하도록 새 클래스를 싱글 톤 인스턴스로 등록 할 수도 있습니다.

3

IoC 컨테이너의 맥락에서 '싱글 톤으로 변환'하는 것은 다소 모호합니다. singleton design pattern을 의미하는 경우 IoC 세계에서 더 나은 대안이 있으므로 아마 그렇게하지 말아야합니다.

IoC 컨테이너는 구성 요소 간의 종속성을 해결하고 구성 요소의 수명을 관리하는 두 가지 주요 역할을 수행합니다. 컨테이너는 구성 요소 인스턴스를 만들고 파괴 할시기를 결정하여 해당 구성 요소의 수명을 관리합니다.

예를 들어 container.Resolve<SiteInfo>()을 호출 할 때 컨테이너는 기존 SiteInfo 인스턴스를 재사용할지 아니면 새 인스턴스를 만들지 결정해야합니다. 컨테이너는 어떻게 결정합니까? 글쎄요, 컨테이너에 SiteInfo를 등록 할 때 컨테이너에 어떻게 동작시킬 것인지 알려줄 수 있습니다. Singleton으로 등록하면 컨테이너는 container.Resolve<SiteInfo>()에 대한 첫 번째 호출에서 SiteInfo 인스턴스 만 만듭니다. 후속 호출에서 기존 SiteInfo 인스턴스를 다시 사용합니다.

싱글 톤 패턴에 비해이 기술의 장점은 유연성입니다. 디자인 패턴을 사용하는 경우 SiteInfo 클래스는 리터 터를 제외하고는 항상 싱글 톤입니다. 컨테이너를 사용하여 수명을 관리하면 나중에 마음을 바꿀 수 있으며 컨테이너 등록 코드 만 변경할 수 있습니다. 구성 요소의 사용자는 컨테이너가 새 인스턴스를 제공하거나 기존 인스턴스를 다시 사용할 필요가 있는지 여부를 신경 써야 할 필요는 없으며 걱정하지 않아도됩니다. 단지 container.Resolve()을 호출하기 만하면됩니다.

나는 윈저 (내가 Autofac를 사용)에 익숙하지 해요,하지만 당신이 싱글로 구성 요소를 등록하는 두 가지 방법이 것 같습니다 (나는 이것이 잘못되면 누군가가 나를 해결 확신) :

container.AddComponentLifeStyle<SiteInfo>(LifestyleType.Singleton) 

또는

container.Register(Component.For<SiteInfo>() 
        .LifeStyle.Singleton); 

그러나 경고의 말씀. 귀하의 예제에서 SiteInfo 클래스는 _SiteRepository 클래스에 종속됩니다. 따라서 _SiteRepository 인스턴스 을 컨테이너에 싱글 톤으로 등록해야 컨테이너가 SiteInfo를 해결할 때 사용할 수 있습니다. 이 _SiteRepository 인스턴스는 컨테이너의 수명 동안, 즉 웹 응용 프로그램의 수명 동안 메모리에 남아 있습니다. 이는 이것이 싱글 톤이기 때문입니다. 저장소가 DB 연결을 계속 열어두면 동일한 연결이 열린 상태로 유지됩니다.

이러한 이유로 웹 요청마다 대체 라이프 스타일을 사용할 수 있습니다. 즉, 컨테이너는 웹 요청 당 한 번씩 SiteInfo 클래스의 새 인스턴스를 만듭니다. 웹 요청 별 라이프 스타일은 another question에서 논의됩니다.

관련 문제