문제

나는 MSDN에 관한 기사를 연합 (의존성 주입, 통제 역전)에 관한 기사를 읽었지만 간단한 용어 (또는 간단한 예)로 설명해야한다고 생각합니다. 나는 MVPC 패턴에 익숙하지만 (우리는 여기에서 사용합니다), 나는 아직이 통일을 이해할 수는 없으며, 그것이 우리의 애플리케이션 디자인의 다음 단계라고 생각합니다.

도움이 되었습니까?

해결책

Unity는 IOC "컨테이너"입니다. Google StructureMap을 대신 사용해보십시오. IOC 물건이 당신에게 새로운 일이있을 때, 나는 조금 더 쉽게 생각합니다.

기본적으로 IOC를 이해하면 객체가 생성 될 때 컨트롤을 반전시키는 것임을 이해합니다.

IOC없이 :

public class MyClass
{
   IMyService _myService; 

   public MyClass()
   {
      _myService = new SomeConcreteService();    
   }
}

IOC 컨테이너와 함께 :

public class MyClass
{
   IMyService _myService; 

   public MyClass(IMyService myService)
   {
      _myService = myService;    
   }
}

IOC가 없으면 ImyService에 의존하는 클래스는 사용할 수있는 콘크리트 버전의 사용할 서비스가 필요합니다. 그리고 그것은 여러 가지 이유가 나쁘다 (당신은 당신의 클래스를 Imyservice의 특정 콘크리트 버전에 결합했을 때, 쉽게 테스트 할 수없고 쉽게 변경할 수 없음 등).

IOC 컨테이너를 사용하면 해당 종속성을 해결하도록 컨테이너를 "구성"합니다. 따라서 생성자 기반 주입 방식을 사용하면 인터페이스를 ImyService 종속성으로 전달하여 생성자로 전달합니다. 컨테이너로 MyClass를 만들 때 컨테이너가 ImyService 종속성을 해결합니다.

StructureMap을 사용하면 컨테이너 구성이 다음과 같습니다.

StructureMapConfiguration.ForRequestedType<MyClass>().TheDefaultIsConcreteType<MyClass>();
StructureMapConfiguration.ForRequestedType<IMyService>().TheDefaultIsConcreteType<SomeConcreteService>();

그래서 당신이 한 일은 컨테이너에게 "누군가가 imyservice를 요청할 때 그들에게 someconcreteservice의 사본을주십시오"라고 들었습니다. 또한 누군가가 MyClass를 요청할 때 콘크리트 MyClass를 얻는다는 것을 명시했습니다.

그것은 모두 IOC 컨테이너입니다. 그들은 더 많은 일을 할 수 있지만 그것은 그것의 추력입니다. 그들은 당신을위한 종속성을 해결하기 때문에 당신은 필요하지 않습니다 (그리고 당신은 코드 전체에서 "새로운"키워드를 사용할 필요가 없습니다).

최종 단계 : MyClass를 만들 때 다음을 수행합니다.

var myClass = ObjectFactory.GetInstance<MyClass>();

도움이되기를 바랍니다. 저에게 이메일을 보내주십시오.

다른 팁

방금 David Hayden의 30 분 Unity 의존성 주입 IOC 스크린 캐스트를 보았고 예제에 대한 좋은 설명이라고 생각했습니다. 다음은 쇼 노트의 스 니펫입니다.

스크린 캐스트는 Unity IOC의 몇 가지 일반적인 사용법을 보여줍니다.

  • 컨테이너가 아닌 유형을 만듭니다
  • 타이핑 등록 및 해결
  • TypEmappings라는 이름의 등록 및 해결
  • 싱글 톤, Lifetimemanagers 및 ContinerControlledLifetimemanager
  • 기존 인스턴스 등록
  • 기존 인스턴스에 종속성을 주입합니다
  • app.config / web.config를 통해 UnityContainer를 채우십시오
  • 종속성 속성과 달리 주입 API를 통한 종속성 지정
  • 중첩 (부모-자식) 용기 사용

Unity는 다른 많은 사람들과 마찬가지로 도서관입니다. 그래서 주어진.

public interface ICalculator
{
    void Add(int a, int b);
}

public class Calculator : ICalculator
{
    public void Add(int a, int b)
    {
        return a + b;
    }
}

유형의 IOC (Control의 역전)가 요청 될 때 Unity와 같은 라이브러리를 사용하여 계산기를 반환합니다 (이 예제는 기술적으로 올바른 것이 아니라 이론적입니다).

IoCLlibrary.Register<ICalculator>.Return<Calculator>();

그래서 이제 icalculator의 인스턴스를 원할 때 당신은 그냥 ...

Calculator calc = IoCLibrary.Resolve<ICalculator>();

IOC 라이브러리는 일반적으로 유형을 해결할 때마다 싱글 톤을 누르거나 새 인스턴스를 만들도록 구성 할 수 있습니다.

이제 당신이 가질 수있는 icalcatulator에 의존하는 수업이 있다고 가정 해 봅시다.

public class BankingSystem
{
    public BankingSystem(ICalculator calc)
    {
        _calc = calc;
    }

    private ICalculator _calc;
}

그리고 라이브러리를 만들 때 생성자에 객체를 주입하도록 라이브러리를 설정할 수 있습니다.

따라서 DI 또는 종속성 주입은 다른 사람이 요구할 수있는 물체를 주입하는 것을 의미합니다.

이 녀석 WilcoxtUtorials는 초보자를 목표로하는 Unity 컨테이너에 대한 훌륭한 데모를 제공합니다.

1 부: http://www.youtube.com/watch?v=cwwe9z0gyew

2 부: http://www.youtube.com/watch?v=PSIBEVGZQQE

30 분도 채 걸리지 않으면 기본 사항을 이해할 것입니다!

Unity는 IOC입니다. IOC의 요점은 유형 외부의 유형 간의 종속성 배선을 추상화하는 것입니다. 이것은 몇 가지 장점이 있습니다. 우선, 중앙에서 수행되므로 종속성이 변경 될 때 많은 코드를 변경할 필요가 없습니다 (단위 테스트의 경우).

또한 배선이 코드 대신 구성 데이터를 사용하여 수행되면 실제로 배포 후 종속성을 다시 사용하여 코드를 변경하지 않고 응용 프로그램의 동작을 변경할 수 있습니다.

MSDN은 a Unity를 사용한 의존성 주입에 대한 개발자 안내서 유용 할 수 있습니다.

개발자 안내서는 의존성 주입이 무엇인지에 대한 기본 사항으로 시작하며 의존성 주입에 통일을 사용하는 방법의 예를 계속합니다. 2014 년 2 월 현재 개발자 가이드는 2013 년 4 월에 출시 된 Unity 3.0을 다룹니다.

ASP.NET Web API 2에서 의존성 주입의 대부분의 예를 다루고 있습니다.

public interface IShape
{
    string Name { get; set; }
}

public class NoShape : IShape
{
    public string Name { get; set; } = "I have No Shape";
}

public class Circle : IShape
{
    public string Name { get; set; } = "Circle";
}

public class Rectangle : IShape
{
    public Rectangle(string name)
    {
        this.Name = name;
    }

    public string Name { get; set; } = "Rectangle";
}

Diautov2Controller.cs에서 자동 분사 메커니즘이 사용됩니다

[RoutePrefix("api/v2/DIAutoExample")]
public class DIAutoV2Controller : ApiController
{
    private string ConstructorInjected;
    private string MethodInjected1;
    private string MethodInjected2;
    private string MethodInjected3;

    [Dependency]
    public IShape NoShape { get; set; }

    [Dependency("Circle")]
    public IShape ShapeCircle { get; set; }

    [Dependency("Rectangle")]
    public IShape ShapeRectangle { get; set; }

    [Dependency("PiValueExample1")]
    public double PiValue { get; set; }

    [InjectionConstructor]
    public DIAutoV2Controller([Dependency("Circle")]IShape shape1, [Dependency("Rectangle")]IShape shape2, IShape shape3)
    {
        this.ConstructorInjected = shape1.Name + " & " + shape2.Name + " & " + shape3.Name;
    }

    [NonAction]
    [InjectionMethod]
    public void Initialize()
    {
        this.MethodInjected1 = "Default Initialize done";
    }

    [NonAction]
    [InjectionMethod]
    public void Initialize2([Dependency("Circle")]IShape shape1)
    {
        this.MethodInjected2 = shape1.Name;
    }

    [NonAction]
    [InjectionMethod]
    public void Initialize3(IShape shape1)
    {
        this.MethodInjected3 = shape1.Name;
    }

    [HttpGet]
    [Route("constructorinjection")]
    public string constructorinjection()
    {
        return "Constructor Injected: " + this.ConstructorInjected;
    }

    [HttpGet]
    [Route("GetNoShape")]
    public string GetNoShape()
    {
        return "Property Injected: " + this.NoShape.Name;
    }

    [HttpGet]
    [Route("GetShapeCircle")]
    public string GetShapeCircle()
    {
        return "Property Injected: " + this.ShapeCircle.Name;
    }

    [HttpGet]
    [Route("GetShapeRectangle")]
    public string GetShapeRectangle()
    {
        return "Property Injected: " + this.ShapeRectangle.Name;
    }

    [HttpGet]
    [Route("GetPiValue")]
    public string GetPiValue()
    {
        return "Property Injected: " + this.PiValue;
    }

    [HttpGet]
    [Route("MethodInjected1")]
    public string InjectionMethod1()
    {
        return "Method Injected: " + this.MethodInjected1;
    }

    [HttpGet]
    [Route("MethodInjected2")]
    public string InjectionMethod2()
    {
        return "Method Injected: " + this.MethodInjected2;
    }

    [HttpGet]
    [Route("MethodInjected3")]
    public string InjectionMethod3()
    {
        return "Method Injected: " + this.MethodInjected3;
    }
}

Div2Controller.cs에서 모든 것이 종속성 구성 Resolver 클래스에서 주입됩니다.

[RoutePrefix("api/v2/DIExample")]
public class DIV2Controller : ApiController
{
    private string ConstructorInjected;
    private string MethodInjected1;
    private string MethodInjected2;
    public string MyPropertyName { get; set; }
    public double PiValue1 { get; set; }
    public double PiValue2 { get; set; }
    public IShape Shape { get; set; }

    // MethodInjected
    [NonAction]
    public void Initialize()
    {
        this.MethodInjected1 = "Default Initialize done";
    }

    // MethodInjected
    [NonAction]
    public void Initialize2(string myproperty1, IShape shape1, string myproperty2, IShape shape2)
    {
        this.MethodInjected2 = myproperty1 + " & " + shape1.Name + " & " + myproperty2 + " & " + shape2.Name;
    }

    public DIV2Controller(string myproperty1, IShape shape1, string myproperty2, IShape shape2)
    {
        this.ConstructorInjected = myproperty1 + " & " + shape1.Name + " & " + myproperty2 + " & " + shape2.Name;
    }

    [HttpGet]
    [Route("constructorinjection")]
    public string constructorinjection()
    {
        return "Constructor Injected: " + this.ConstructorInjected;
    }

    [HttpGet]
    [Route("PropertyInjected")]
    public string InjectionProperty()
    {
        return "Property Injected: " + this.MyPropertyName;
    }

    [HttpGet]
    [Route("GetPiValue1")]
    public string GetPiValue1()
    {
        return "Property Injected: " + this.PiValue1;
    }

    [HttpGet]
    [Route("GetPiValue2")]
    public string GetPiValue2()
    {
        return "Property Injected: " + this.PiValue2;
    }

    [HttpGet]
    [Route("GetShape")]
    public string GetShape()
    {
        return "Property Injected: " + this.Shape.Name;
    }

    [HttpGet]
    [Route("MethodInjected1")]
    public string InjectionMethod1()
    {
        return "Method Injected: " + this.MethodInjected1;
    }

    [HttpGet]
    [Route("MethodInjected2")]
    public string InjectionMethod2()
    {
        return "Method Injected: " + this.MethodInjected2;
    }
}

종속성 레졸버 구성

public static void Register(HttpConfiguration config)
{
    var container = new UnityContainer();
    RegisterInterfaces(container);
    config.DependencyResolver = new UnityResolver(container);

    // Other Web API configuration not shown.
}

private static void RegisterInterfaces(UnityContainer container)
{
    var dbContext = new SchoolDbContext();
    // Registration with constructor injection
    container.RegisterType<IStudentRepository, StudentRepository>(new InjectionConstructor(dbContext));
    container.RegisterType<ICourseRepository, CourseRepository>(new InjectionConstructor(dbContext));

    // Set constant/default value of Pi = 3.141 
    container.RegisterInstance<double>("PiValueExample1", 3.141);
    container.RegisterInstance<double>("PiValueExample2", 3.14);

    // without a name
    container.RegisterInstance<IShape>(new NoShape());

    // with circle name
    container.RegisterType<IShape, Circle>("Circle", new InjectionProperty("Name", "I am Circle"));

    // with rectangle name
    container.RegisterType<IShape, Rectangle>("Rectangle", new InjectionConstructor("I am Rectangle"));

    // Complex type like Constructor, Property and method injection
    container.RegisterType<DIV2Controller, DIV2Controller>(
        new InjectionConstructor("Constructor Value1", container.Resolve<IShape>("Circle"), "Constructor Value2", container.Resolve<IShape>()),
        new InjectionMethod("Initialize"),
        new InjectionMethod("Initialize2", "Value1", container.Resolve<IShape>("Circle"), "Value2", container.Resolve<IShape>()),
        new InjectionProperty("MyPropertyName", "Property Value"),
        new InjectionProperty("PiValue1", container.Resolve<double>("PiValueExample1")),
        new InjectionProperty("Shape", container.Resolve<IShape>("Rectangle")),
        new InjectionProperty("PiValue2", container.Resolve<double>("PiValueExample2")));
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top