1

화합을 시작하려고하는데이 특정 문제에 대한 도움을 찾고 있습니다. 이미 종속성 주입/화합은 프로그래밍 방식으로이 작업을 수행하는 방법이지만 종속성 속성이 표시된 멤버가 언제/언제 채워지는지 이해할 수 없습니다.정적 멤버 (예 : 정적 클래스 프로그램)에 대한 Unity DI/멤버가 채워지는 시간

class Program 
{ 
    static Program()   
    { 
     uContainer = new UnityContainer(); 
     var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); 
     section.Configure(uContainer); 
    } 

    private static IUnityContainer uContainer; 

    [InjectionMethod] 
    public static void InjectTrace(ITraceManager traceManager) 
    { 
     trace = traceManager; 
    } 

    [Dependency] 
    public static ITraceManager trace { get; set; }// = /*new WebTraceManager("C:\\","trace",true);//*/new EnterpriseLibaryLoggingWrapper(false); 

    static void Main(string[] args) 
    { 
     //Programmatically inject dependency 
     // TODO: Do this via attributes 
     //UnityContainer myContainer = new UnityContainer(); 
     //UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); 

     //section.Containers["containerOne"].Configure(myContainer); 
     //trace = myContainer.Resolve<ITraceManager>(); 
     trace.ProgramStatus("Start"); 
     trace.ProgramStatus("End"); 
     Console.ReadLine(); 
    } 
} 

프로그래밍 방식으로 추적 속성을 설정하는 주석 처리되지 않은 섹션은 잘 작동합니다. 그러나 "Dependency"속성을 사용하면 속성이 채워지지 않습니다. 화합 컨테이너에 누락 된 전화가 있습니까? 도움 주셔서 감사합니다.

스티브의 조언에 따라 내가 대신 정적 클래스의 인스턴스를 사용하여 예제를 변경했습니다 :

static Program() 
    { 
     uContainer = new UnityContainer(); 
     var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); 
     section.Configure(uContainer); 
     Instance = uContainer.Resolve<Program>(); 
    } 

    Program(ITraceManager traceManager) 
    { 
     trace = traceManager; 
    } 

    static readonly Program Instance; 

    //Do not use Dependency Attribute 
    //[Dependency] 
    public ITraceManager trace { get; set; }// = /*new WebTraceManager("C:\\","trace",true);//*/new EnterpriseLibaryLoggingWrapper(false); 

    static void Main(string[] args) 
    {   
     Instance.Run(); 
    } 

    void Run() 
    {    
     trace.ProgramStatus("Start"); 
     trace.ProgramStatus("End"); 
     Console.ReadLine(); 
    } 

을하지만

Instance = uContainer.Resolve<Program>(); 

를 호출 할 때, 내가 말해 예외를받을 해당 프로그램 컨테이너 내에 등록되지 않았습니다. 그게 사실이긴하지만 should'nt 유니티는 대신 의존성을 가진 프로그램 코드 타입의 프로그램을 반환합니까? 내가 웹에서 발견 예제는 항상 내가 마지막으로 사출 생성자 샘플 문제를 발견이

IUnityContainer uContainer = new UnityContainer(); 
MyObject myInstance = uContainer.Resolve<MyObject>(); 

같은 생성자 주입을 사용, 물론 생성자는 공개한다. 예외 메시지는 나를 조금 혼란스럽게 만들었다.

답변

7

몇 가지 포인트 :

  • 현재 완전히 XML의 컨테이너를 구성하는 것. 하지 마세요! XML로 구축 (배포 구성) 한 후에 실제로 변경할 수있는 종속성 만 구성해야합니다. XML 기반의 설정은 매우 약하고, 컴파일 타임 지원이 없으며, 인텔리 센스 지원이 부족하고, 표현력이 부족하기 때문에 나머지는 코드 기반 구성을 사용하십시오.
  • 구성 요소를 초기화하는 데 메서드 삽입을 사용하지 마십시오. 이로 인해 Temporal Coupling이됩니다. 종속성을 주입하는 주요 방법은 생성자 주입을 사용하는 것입니다. 생성자 매개 변수에 대한 모든 종속성을 정의하십시오. 종속성이있는 모든 유형에는 필요한 모든 종속성을 포함하는 single public constructor이 있어야합니다. Unity는 자동으로 해당 생성자를 찾고 해당 생성자를 호출하고 종속성을 주입하는 방법을 알고 있습니다.
  • 속성을 전혀 사용하지 마십시오! 이것은 응용 프로그램 코드가 DI 컨테이너의 존재를 잊어 버리는 동안 코드를 사용 된 컨테이너에 연결합니다. 다시 말하지만, 생성자 주입을 계속 사용하십시오.
+0

스티븐, 안녕하세요. 힌트 (생성자 삽입)에 따라 예제를 수정했지만 프로그램 클래스가 등록되지 않았으므로 삽입 된 tracemanager 대신 container.resolve를 시도 할 때 예외가 발생합니다. 당신은 예를 들어 오크를 기쁘게 할 수 있겠습니까? thanks – user1430306

+0

"Unity는 자동으로 해당 생성자를 찾고 해당 생성자를 호출하고 종속성을 주입하는 방법을 알고 있습니다." 이게 뭐니? : MyObject myInstance = uContainer.Resolve (); public MyObject (IDependency1 dep1) {this.dependency1 = dep1;} – user1430306

+0

미안 해요. 내 코드에서 바보 같은 실수였습니다. 생성자는 public이 아니었지만, Unity에 대해서는 공개되어 있어야합니다! – user1430306