2016-07-23 2 views
0

나는 ioc를 좋아합니다. 이전에, 저는 Java에서 Spring을 사용합니다. 이제 C#에서 DI를 사용하겠습니다. castle.windsor를 발견했습니다. 그러나 그것은 주입 클래스를 지시하는 것처럼 보이지 않습니다.인터페이스를 사용하지 않고 구성 요소를 주입 할 수 있습니까? 윈저

자, 시도해 보니 실패했습니다 .... 누군가, 고칠 수 있도록 도와 줄 수 있습니까? 또는, 어떤 DI 프레임 워크를 사용할 수 있습니까?

Program.cs

using System; 
using Castle.MicroKernel.Registration; 
using Castle.MicroKernel.SubSystems.Configuration; 
using Castle.Windsor; 

namespace InjectionConsole 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var container = new WindsorContainer(); 
      container.Install(new MainInstaller()); 

      var service1 = container.Resolve<Service1>(); 

      service1.Say(); 

      // clean up, application exits 
      container.Dispose(); 

      Console.ReadKey(); 
     } 
    } 

    class MainInstaller : IWindsorInstaller 
    { 
     public void Install(IWindsorContainer container, IConfigurationStore store) 
     { 
      container.Register(Classes.FromThisAssembly()); 
     } 
    } 
} 

Service1.cs

using System; 

namespace InjectionConsole 
{ 
    class Service1 
    { 
     private Service2 Service2 { get; set; } 

     public void Say() 
     { 
      Console.WriteLine("Hello, I m Service 1, let me call Service 2"); 

      Service2.Say(); 
     } 
    } 
} 

Service2.cs는

using System; 

namespace InjectionConsole 
{ 
    class Service2 
    { 
     public void Say() 
     { 
      Console.WriteLine("Hello, I m Service 2"); 
     } 
    } 
} 
+0

"제어 반전"의 주된 포인트는 의존 클래스를 반전하여 종속 클래스가 실제 구현이 아닌 서비스의 인터페이스에 종속되도록하는 것입니다. 인터페이스를 사용하지 않는다면 IOC 컨테이너와 언급 된 패턴의 핵심 이점을 없앨 수 있습니다. –

답변

0

내 대답은 또 다른 유사하지만 하나의 헤어 분할의 차이 : 우선

public class Service1 
{ 
    private readonly Service2 _service2; 

    public Service1(Service2 service2) { 
     _service2 = service2; 
    } 

    public void Say() 
    { 
     Console.WriteLine("Hello, I m Service 1, let me call Service 2"); 

     _service2.Say(); 
    } 
} 

는, 클래스 자체가 있는지 여부를 정확히 같은 방식으로 기록 될 것입니다 윈저와 같은 컨테이너를 사용하고 있습니다. 클래스는 어딘가에서 종속성 (Service2의 인스턴스)을 "가져와야합니다. 그래서 우리는 이것을 생성자에 넣습니다. Service1은 무엇이든지 작성하여 Service2을 제공 할 것으로 예상합니다. 컨테이너를 사용하기 때문에 컨테이너는 Service1을 생성하고 생성자에서 Service2이 필요하다는 것을 확인하고이를 제공합니다.

_service2 만들기 readonly 필드는이 생성 된 후에는 Service1_service2 값 더 이상 제어 할 수없는 (생성자의 실행이 행해진 다) 강조. 설정되었으므로 변경할 수 없으며 Service1 내에 있지 않습니다. 그것은 우리가 원하지 않기 때문에 중요하다 Service1 to 통제 그 종속성. 우리는 에 종속성을 요구하는이 필요합니다. 그것은 전달 된 값을 가져 와서 사용합니다.

다시 말하면 헤어 스타일 차이입니다. 이 아니면 _service2readonly으로 변경하면 어쨌든 변경하지 않을 것입니다. 그러나 이것은 당신이 으로 바꿀 수 없다는 것을 분명히합니다.

+0

답변 해 주셔서 감사합니다. 나는 너에게 동의한다. 그러나 실패 이유는 "Castle.MicroKernel.ComponentNotFoundException '유형의 처리되지 않은 예외가 Castle.Windsor에서 발생했습니다.dll " – JonasGao

+0

등록되지 않은 구성 요소는 무엇입니까? –

1

나는 당신이 당신의 서비스 1 인스턴스에서 서비스 2를 해결 싶어 가정합니다. 당신은 생성자 주입에 의해 그것을 달성 할 수

using System; 

namespace InjectionConsole 
{ 
    class Service1 
    { 
     public Service1(Service2 s2) { 
      this.Service2 = s2; 
     } 

     private Service2 Service2 { get; set; } 

     public void Say() 
     { 
      Console.WriteLine("Hello, I m Service 1, let me call Service 2"); 

      Service2.Say(); 
     } 
    } 
} 
+0

답변 해 주셔서 감사합니다. 그러나 실패 이유는 "Castle.Windsor.dll에서 'Castle.MicroKernel.ComponentNotFoundException'유형의 처리되지 않은 예외가 발생했습니다." – JonasGao

1

Service1Service2 클래스는 public으로 표시되어 있지 않으므로 기본적으로 내부 클래스가됩니다. Classes.FromThisAssembly() 메서드는 공용 형식 만로드합니다. 명시 적으로 공용 형식도로드하지 않는다면 (이 방법은 권장하지 않습니다!). Castle windsor GitHub 문서 페이지에서 the docs을 확인하십시오.

관련 문제