2009-10-23 7 views
4

최근에 처음으로 IoC 컨테이너를 사용하기 시작했으나이를 사용하는 모범 사례에 대한 교육을받지 못했습니다. 더 구체적으로 나는 과 함께 왔기 때문에 C# .NET 프로젝트에서 Unity을 사용하고 있으며, 사용하기 시작했다.일반적인 IoC 컨테이너 사용 - 데이터를 줄 아래로 전달

컨테이너를 사용하여 "최상위 수준"개체를 해결하고 컨테이너를 기반으로 주입 된 올바른 개체를 가져옵니다. 그러나 어린이와 어린이가있는 객체가있을 때 명확하게 모범 사례를 볼 수 없으며 IoC 컨테이너의 모든 데이터가 중간에 있어야하지만 중간에 있어야합니다. 일반적으로 IoC 컨테이너를 어떻게 구성할까요?

처음에는 최상위 레벨의 컨테이너에서 필요한 데이터를 추출하고이 데이터를 전달하는 대신 컨테이너를 전달하는 것이 좋다고 생각합니다. 그런데 주입 된 인터페이스 외에도 다른 특정 데이터를 가져 오는 객체에 도달하면 문제가 발생하며 객체를 확인한 후에 속성 또는 init 메소드를 통해 주입하지 않는 것이 좋습니다.

나는 이것이 충분히 명확했으면 좋겠지 만 허구의 (그리고 약간 어리석은) 예를 보자.

class Employee 
{ 
    private ICommands _commands; 
    priate List<Customer> _customers = new List<Customer>(); 
    public Employee(ICommands commands) 
    { 
     _commands = commands; 
    } 
    public void AddCustomer(string customerName) 
    { 
     var customer = new Customer(customerName, _commands); 
     _customers.Add(customer); 
    } 
} 

class Customer 
{ 
    private string _name; 
    private ICommands _commands; 
    priate List<Case> _cases = new List<Case>(); 
    public Customer(string, name, ICommands commands) 
    { 
     _name = name; 
     _commands = commands; 
    } 
    public void AddCase() 
    { 
     var case = new Case(_commands); 
     _cases.Add(case); 
    } 
} 

class Case { 
    private ICommands _commands; 
    public Customer(ICommands commands) 
    { 
     _commands = commands; 
    } 
    public void TriggerCommands() 
    { 
     _command.TriggerSomething(); 
    } 
} 

그래서이 예제는별로 의미가 없지만 본질은 내가해야 할 것과 동일합니다. 일부는 내 ViewModel 클래스를 통해 줄을 전달하는 응용 프로그램 명령이 있는데, 그 중 일부는 명령을 표시하여 뭔가를 표시 할 수 있어야하기 때문입니다. 나는 또한 공통 저장 공간을 가지고 있는데, 이는 몇몇 클래스들에 필요할 수도 있지만 현재는 통과되어 중간 클래스들에 저장된다. 명령 만 사용하면 명령이나 컨테이너를 저장할 때 큰 문제는 없지만 일반적인 IoC 사용법에서는 IoC 컨테이너를 대신 사용하여 개체를 줄 아래로 확인할 때 사용합니까? 고객 이름과 같은 특정 데이터는 어떻게됩니까? Resolve()에서이 값을 전달할 수 없으므로 이후에 주입해야합니다.

죄송합니다 - 이것은 내가 만들 수있는만큼 짧았습니다. 같은 길이의 답변을 요구하지 않습니다 ;-) .. 그냥; IoC 컨테이너에서 이와 같은 작업을 수행하는 가장 좋은 방법은 무엇입니까?

답변

3

귀하의 질문을 이해할 수 있을지 잘 모르겠습니다. 그러나 나는 당신이 용기를 전혀 지나쳐야한다고 생각하지 않는다. 컨테이너에 대한 래퍼 클래스를 만드는 것이 훨씬 쉽습니다. 예를 들면 다음과 같습니다.

public class IoCContainer 
{ 
    private static ContainerType = null; 

    public static ContainerType Instance 
    { 
    get 
    { 
     if (_container == null) 
     { 
     string configFileName = ConfigurationManager.AppSettings[ConfigFileAppSettingName]; 
     _container = new WindsorContainer(new XmlInterpreter(configFileName)); 
     } 

     return _container; 
    } 
    } 
} 

이제 코드에서이 모든 것을 호출합니다.

IoCContainer.Instance.Resolve<IAwesomeService>(); 

이 방법이 도움이됩니까? 이 질문에 대답하는 경우

+1

감사합니다. 나는 이것이 도움이된다고 생각한다. 이것이 가장 좋은 방법으로 간주됩니까? 이것은 어쨌든 그것을 사용하지 않을 클래스를 통해 아무 것도 전달할 필요가 없다는 것을 의미합니다. 이것은 좋은 것입니다 ..! – stiank81

+0

이와 같은 정적 클래스 솔루션을 시도합니다. 당신의 도움을 주셔서 감사합니다! – stiank81

+0

도와 주시겠습니까?) –

2

는 잘 모르겠지만, 나는 좋은 방법은 (내가 생각하는 다른 IOC의 엔진에도 적용) 유니티 컨테이너를 사용하는 응용 프로그램에 따라 행동하는 것을 말할 것입니다 :

  • 필수 종속성이 생성자에 으로 지정되도록 클래스를 디자인하십시오. 이렇게하면 개체를 새로 만들 필요가없는 한 Unity를 명시 적으로 처리 할 필요가 없습니다.
  • 당신이 당신의 클래스 내에서 새로운 객체 를 작성 ( IUnityContainer에 대한 참조로)뿐만 아니라 생성자 에서 유니티 용기 자체를 통과하고 Resolve 방법을 사용하여 모든 새 객체 인스턴스를 작성해야하는 경우. 이 아닌 개체에 대해서도 컨테이너는 적절한 인스턴스를 제공하고 나중에 클라이언트 코드를 변경하지 않고 이전에 등록되지 않은 유형을 등록하도록 결정할 수 있습니다.
  • 명시 적 값을 해석 된 개체로 전달하는 것과 같이 형식을 등록 할 때 구체적인 주입 멤버를 지정할 수 있습니다 (RegisterType 클래스의 InjectionMembers 매개 변수 참조).
+0

이것은 Resolve를 사용하여 객체를 생성하는 경우 생성자에 명시 적 값을 전달하는 방법의 문제를 만날 때까지 달성하려고 시도한 것입니다. 그러나 당신이 언급 한 InjectionMembers 매개 변수를 살펴볼 것입니다. 그러나 IoC 컨테이너를 지나가는 것에 대한 조언을 읽었지만, 괜찮 았다고 말하는 것입니까? – stiank81

+1

내 관점은 : IoC 컨테이너를 통해 모든 객체를 얻는 데 전체 응용 프로그램 디자인을 기반으로하는 경우 동일한 방법으로 IoC 컨테이너를 얻는 것보다 더 일관성이있는 것은 무엇입니까? – Konamiman

0

특정 컨테이너로 초기화하고 Resolve, Resolve (...)와 같은 메소드를 구현하는 정적 클래스 IoC를 정의하면 실제 작업을 컨테이너 인스턴스에 위임합니다. 이 인스턴스를 필드 나 속성에 저장합니다.) 이렇게하면 주위에 아무 것도 전달할 필요가 없습니다.

IoC.Resolve<SomeType>(); 

코드의 어느 곳에서나 사용할 수 있습니다.

특정 데이터 : 일부 컨테이너는이 매개 변수에 따라 매개 변수를 사용하고 해결됩니다 (Autofac에는 이러한 종류의 기능이 있음). 또는 고객 이름과 같은 매개 변수 집합을 허용하고 해당 객체 인스턴스를 반환하는 메소드가있는 팩토리 클래스를 항상 만들 수 있습니다.

+1

Thx. 정적 IoC 클래스를 사용하는 것 같은 것은 대중적인 선택입니다. 합리적으로 들린다. – stiank81

+0

칼의 대답에 대한 내 의견보기. –

1

엔티티에 대한 팩토리를 선언해야하는 것 같습니다. 생성자 삽입을 통해 팩토리를 해석하고 Create 메소드를 통해 데이터 값을 전달하십시오. 다른 모든 종속성은 팩토리의 생성자를 통해 확인되어야합니다.

대답 : this 대답을 참조하십시오.