[DI] 의존성과 계층화

2019. 12. 16. 17:21
728x90
반응형

 

모든 소프트웨어는 의존성(dependency) 를 가지고 있다. 

1. 같은 기반코드를 이용하는 코드에 대한 First-Party 의존성.

2. 외부 어셈블리에 대한 Third-Party 의존성.

3. 닷넷 프레임워크에 대한 보편적인 의존성

일 수 있으며, 웬만한 프로젝트라면 이 세가지 의존성을 모두 찾아볼수 있다.

 

의존성은 호출자 코드로부터 기능을 추상화 한다. 모든 의존성에 대한 관리만큼은 정확히 해야 한다.

의존성 체인을 제대로 관리하지 못하면, 개발자들은 존재할 필요가 없는 의존성 때문에 불필요한 어셈블리 참조로 복잡하게 꼬인 코드를 관리해야 한다.

계층화 (Layering)는 가장 일반적인 아키텍처 패턴 중 하나이다.

 


의존성의 정의

의존성( Dependency )은 별개의 두 엔티티(entity) 사이의 연관 관계로 인해, 어느 한 엔티티가 다른 엔티티의 기능 없이는 (혹은 존재 없이는) 자신의 기능을 실행하지 못하는 관계를 의미합니다.

엔티티는 주로 어셈블리를 의미하며, 어셈블리 A 가 다른 어셈블리 B를 사용하고 있다면, A가 B에 의존적이라고 말할 수 있습니다. 이런 관계를 서술하는 가장 일반적인 방법은 A가 B의 클라이언트(client) 이고, B는 A의 서비스(service) 라고 표현하는 방법이다.

 


퍼스트파티 의존성 - 간단예제

하나의 솔루션에 두개의 프로젝트를 생성했습니다.  

ClassLibrary 는 클래스 라이브러리 프로젝트이며, 

SimpleDependency 는 콘솔 앱 프로젝트입니다. (.NET Framework) 기반

 

SimpleDependency 프로젝트에 ClassLibrary 프로젝트를 참조한 뒤, 별다른 코딩없이 실행시켜봅니다.

디버그로 실행한 뒤, 디버그 > 창 > 모듈 을 선택하면, 

현재 로드된 모듈에 대한 정보를 볼 수 있습니다.

ClassLibrary를 참조 하였음에도, 실질적인 사용 부분이 없다면 로드되지 않는 모습을 볼 수 있습니다.

 

어플리케이션이 ClassLibrary 어셈블리가 제공하는 기능을 전혀 사용하지 않기 때문에 닷넷 런타임이 해당 모듈을 로드하지 않은 것입니다.

 

using System;

namespace SimpleDependency
{
    class Program
    {
        static void Main(string[] args)
        {
            var service = new ClassLibrary.Reward();
            service.SendReward();
            Console.ReadKey();
        }
    }
}

 

실질적으로 사용하는 코드를 작성하고 디버그 모드로 실행 했을 때 모듈창에서 ClassLibrary.dll 이 로드 된 것을 볼 수 있습니다. 실제 사용하는 순간 모듈을 로드 하며, 같은 솔루션 내에 구현되어 있는, 이를 일반적으로 First-Party 의존성이라고 합니다.


프레임워크 의존성

위 두 프로젝트는 닷넷 프레임워크 어셈블리들에 의존성을 가지고 있습니다. SimpleDependency 프로젝트는 닷넷프레임워크에 대한 여러가지 참조를 가지고 있고, 이런 의존성은 대부분 모든 콘솔 어플리케이션 프로젝트가 기본적으로 가지게 되는 의존성입니다.

 

프레임워크 어셈블리는 항상 로드된다.

다른 의존성과는 달리 닷넷 프레임워크 어셈블리를 참조하면, 이 어셈블리들은 항상 로드된다는 점이다.
이런 어셈블리들을 실제로 사용하지 않는다 해도 어플리케이션을 시작할때 자동으로 로드한다.
다행인 점은 솔루션 내의 여러 프로젝트가 모두 같은 어셈블리를 참조하면 단 하나의 어셈블리 인스턴스만 메모리에 로드되어 공유된다는 점이다.

 

 

기본 참조 목록

  Visual Studio\Common7\IDE\ProjectTemplates\CSharp\Windows\1042\ConsoleApplication
  
  <ItemGroup>
    <Reference Include="System"/>
    $if$ ($targetframeworkversion$ >= 3.5)
    <Reference Include="System.Core"/>
    <Reference Include="System.Xml.Linq"/>
    <Reference Include="System.Data.DataSetExtensions"/>
    $endif$
    $if$ ($targetframeworkversion$ >= 4.0)
    <Reference Include="Microsoft.CSharp"/>
    $endif$
    <Reference Include="System.Data"/>
    $if$ ($targetframeworkversion$ >= 4.5)
    <Reference Include="System.Net.Http"/>
    $endif$
    <Reference Include="System.Xml"/>
  </ItemGroup>

콘솔 어플리케이션에 대한 기본 참조 목록은 위 경로에 템플릿으로 정의되어 있다.

 

 


서드파티 의존성

 

개발자에 의해 개발된 어셈블리에 대한 의존성입니다. 닷넷 프레임워크가 제공하지 않는 기능에 대해, 퍼스트 파티 의존성을 추가할 수 있으나 너무 많은 노력이 듭니다. 이런 경우 미리 만들어진 솔루션을 선택할 수 있는데요.

예를 들어 객체 관계 매퍼 (ORM, Object Relational Mapper) 같은 경우입니ㅏㄷ.

 

서드파티 의존성을 선택하는 가장 중요한 이유는, 어떤 기능이나 인프라스트럭처를 직접 구현하느라 많은 노력을 투자하는 대신, 이미 만들어진 것을 가져와 적절히 활용할 수 있기 때문입니다.

 

또한 Nuget을 이용하여 서드파티 의존성을 관리하는 방법도 있습니다.

 

 

 

728x90

+ Recent posts