예를 들어, Object A 와 Object B 를 가진 Client 를 만든다면 기존에는 아래와 같다.
Object A,Object B생성 ->Object A,Object B를 이용하여Client생성
Dependency Injection 을 이용한다면 아래와 같이 순서가 바뀐다.
비어있는
Client생성 ->Object A,Object B생성 ->Client에Object A와Object B를 주입
여기서 주입은 프레임워크를 통해 수행한다.
개발환경 - C# (Visual Studio)
using ProjectA;
class DIMain
{
public void Test1()
{
ProjectATest projectA = new ProjectATest();
projectA.Test();
}
public void Test2()
{
ProjectATest projectA = new ProjectATest();
projectA.Test();
}
public void Test3()
{
ProjectATest projectA = new ProjectATest();
projectA.Test();
}
public void Test4()
{
ProjectATest projectA = new ProjectATest();
projectA.Test();
}
}
DIMain 클래스는 ProjectATest 클래스에 의존하게 되므로 ProjectA 클래스를 ProjectB 클래스로 변경하면 모두 변경해줘야 한다.
using ProjectA;
class DIMain
{
private ProjectATest _project;
public DIMain()
{
_project = new ProjectATest();
}
public void Test1()
{
_project.Test();
}
public void Test2()
{
_project.Test();
}
public void Test3()
{
_project.Test();
}
public void Test4()
{
_project.Test();
}
}
그렇다면 위와 같이 생성자를 통해서 어느 정도의 타이트한 관계를 느슨하게 개선할 수 있다.
하지만 Dependency Injection 과 IoC 를 고려해본다면 현재 동작하는 DIMain 클래스 내부에서가 아닌 외부에서 의존성을 주입해주고자 더 개선하고자 한다.
using ProjectA;
using ProjectB;
using Microsoft.Extensions.DependencyInjection;
// collection 을 통해 ProjectTest Interface와 ProjectTest 클래스 의존성을 주입한다.
ServiceCollection collection = new ServiceCollection();
// 두 번째 인자에 ProjectATest, ProjectBTest 를 선택만 한다면 해당 소스 내 다른 코드들은 수정하지 않아도 된다!
collection.AddScoped<IProjectTest, ProjectBTest>();
// 직접 실행하기 위해 DIMain 클래스를 collection 에 추가한다.
collection.AddScoped<DIMain>();
// BuildServiceProvider() 메소드를 통해 provider 를 생성하고 GetService 로 DIMain 객체를 생성한다.
ServiceProvider provider = collection.BuildServiceProvider();
DIMain diMain = provider.GetService<DIMain>();
diMain.Test1();
class DIMain
{
private IProjectTest _project;
public DIMain(IProjectTest project)
{
_project = project;
}
public void Test1()
{
_project.Test();
}
public void Test2()
{
_project.Test();
}
public void Test3()
{
_project.Test();
}
public void Test4()
{
_project.Test();
}
public static void Main()
{
}
}
따라서 적절하게 Interface 와 Dependency Injection 을 이용한다면 좀 더 느슨해진 객체 간의 관계를 만들어갈 수 있다.
Dependency Injection 이 고려되지 않는다면 객체 간의 관계가 타이트해지면서 (= 의존성이 클수록) 수정 사항이 발생하게 되면 코드들을 모두 수정해줘야 한다.