문제

Microsoft의 Unity 프레임 워크와 함께 C#을 사용하고 있습니다. 이 문제를 해결하는 방법은 잘 모르겠습니다. 그것은 아마도 Unity로 DI를 이해하지 못하는 것과 관련이있을 것입니다.

다음 예제 코드를 사용하여 내 문제를 요약 할 수 있습니다.

class Train(Person p) { ... }

class Bus(Person p) { ... }

class Person(string name) { ... }

Person dad = new Person("joe");
Person son = new Person("timmy");

버스의 Resolve Method를 호출 할 때 'Timmy'라는 이름의 사람 '아들'이 주입되었고 열차를 해결할 때 'Joe'라는 이름을 가진 사람 '아빠'가 어떻게 해결 될 수 있습니까?

나는 아마도 명명 된 인스턴스를 사용하고 있다고 생각합니까? 그러나 나는 손실에있다. 모든 도움이 감사하겠습니다.

제쳐두고, 나는 오히려 Iperson 인터페이스를 만들지 않을 것입니다.

도움이 되었습니까?

해결책

이를 해결하는 한 가지 방법은 명명 된 등록이있는 주입 생성자를 사용하는 것입니다.

// Register timmy this way  
Person son = new Person("Timmy");  
container.RegisterInstance<Person>("son", son);  

// OR register timmy this way  
container.RegisterType<Person>("son", new InjectionConstructor("Timmy"));  

// Either way, register bus this way.  
container.RegisterType<Bus>(new InjectionConstructor(container.Resolve<Person>("son")));  

// Repeat for Joe / Train

다른 팁

"Joe"와 "Timmy"가 각각 이름이 지정된 종속성으로 등록하지 않는 한, "Timmy"가 Schoolbus에 주입되어 있는지 확신 할 수 없습니다. 실제로 이름이없는 종속성과 동일한 클래스의 두 인스턴스를 등록하려고하면 모호한 설정이 있으며 해결할 수 없습니다. Person 조금도.

일반적으로, 많은 이름의 인스턴스를 등록해야한다면 아마도 DI를 잘못된 방식으로 진행하고있을 것입니다. DI의 주요 아이디어는 해결하는 것입니다 도메인 서비스 이상 도메인 객체.

DI의 주요 아이디어는 당신이 해결할 수있는 메커니즘을 제공하는 것입니다. 추상 유형 (인터페이스 또는 추상 클래스) 콘크리트 유형으로. 예제에는 추상 유형이 없으므로 실제로는 의미가 없습니다.

Mark Seeman이 제대로 얻었습니다. 그리고 나는 당신의 혼란에 동정합니다. 자동 의존성 주입 컨테이너를 사용하는 법을 배웠을 때 직접 통과했습니다. 문제는 객체를 설계하고 사용하는 유효하고 합리적인 방법이 많이 있다는 것입니다. 그러나 이러한 접근법 중 일부만이 자동 의존성 인젝터 컨테이너와 함께 작동합니다.

나의 개인 역사 : 나는 Unity 또는 Castle Windsor 컨테이너와 같은 제어 용기의 역전을 사용하는 방법을 배우기 오래 전에 물체 구성의 OO 원칙과 통제의 역전을 배웠다. 나는 다음과 같은 코드를 작성하는 습관을 얻었습니다.

public class Foo
{
   IService _service;
   int _accountNumber;

   public Foo(IService service, int accountNumber)
   {
      _service = service;
      _accountNumber = accountNumber;
   }
   public void SaveAccount()
   {
       _service.Save(_accountNumber);

   }
}
public class Program
{
     public static void Main()
     {
        Foo foo = new Foo(new Service(),1234);
        foo.Save();
     }
}

이 디자인에서 FOO 클래스는 계정을 데이터베이스에 저장하는 책임이 있습니다. 이를 위해서는 계정 번호와 더러운 작업을 수행하기 위해 서비스가 필요합니다. 이것은 위에서 제공 한 콘크리트 클래스와 다소 유사하며 각 객체는 생성자에서 고유 한 값을 취합니다. 이것은 자신의 코드로 개체를 인스턴스화 할 때 잘 작동합니다. 적절한 시간에 적절한 값을 전달할 수 있습니다.

그러나 자동 의존성 주입 컨테이너에 대해 알게되었을 때 더 이상 FOO를 손으로 인스턴스화하지 않는다는 것을 알았습니다. 컨테이너는 나에게 생성자 주장을 인스턴스화 할 것입니다. 이것은 Iservice와 같은 서비스에 큰 편리함이었습니다. 그러나 그것은 분명히 정수와 줄 등에 잘 작동하지 않습니다. 이 경우 기본값 (정수의 경우 0)을 제공합니다. 대신, 나는 계정 번호, 이름 등과 같은 상황 별 값을 전달하는 데 익숙했습니다. 그래서 코딩과 디자인 스타일을 다음과 같이 조정해야했습니다.

public class Foo
{
   IService _service;
   public Foo(IService service)
   {
      _service = service;
   }
   public void SaveAccount(int accountNumber)
   {
       _service.Save(accountNumber);

   }
}
public class Program
{
     public static void Main()
     {
        Foo foo = new Foo(new Service());
        foo.Save(1234);
     }
}

두 Foo 클래스는 모두 유효한 디자인 인 것 같습니다. 그러나 두 번째는 자동 의존성 주입으로 사용할 수 있으며 첫 번째는 그렇지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top