의존성 주입을 사용하지 않는 경우:
Car
클래스는Engine
클래스에 직접 의존합니다.Car
클래스 내부에서Engine
객체를 생성하므로,Engine
클래스를 변경하려면Car
클래스를 수정해야 합니다.- 이로 인해 코드의 결합도가 높아지고, 변경과 테스트가 어렵습니다.
의존성 주입을 사용하는 경우:
Car
클래스는IEngine
인터페이스에 의존합니다.- 실제 엔진 구현체는
GasolineEngine
또는ElectricEngine
클래스입니다. - 의존성 주입을 통해
Car
클래스는IEngine
인터페이스의 구현체를 외부에서 주입받습니다. - 이를 통해
Car
클래스는 특정 구현체에 종속되지 않고, 코드의 유연성과 테스트 용이성이 향상됩니다.
1. 인터페이스 정의
우선, 필요한 인터페이스를 정의합니다. 여기서는 엔진(IEngine
)과 자동차(ICar
) 인터페이스를 정의합니다.
1 2 3 4 5 6 7 8 9 10 11 |
public interface IEngine { void Start(); } public interface ICar { void Start(); } |
2. 인터페이스 구현
인터페이스를 구현하는 클래스를 만듭니다. 나중에 요구사항이 변경되어도 쉽게 교체할 수 있도록 인터페이스를 통해 접근합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
public class GasolineEngine : IEngine { public void Start() { Console.WriteLine("Gasoline engine started."); } } public class ElectricEngine : IEngine { public void Start() { Console.WriteLine("Electric engine started."); } } public class Car : ICar { private readonly IEngine _engine; public Car(IEngine engine) { _engine = engine; } public void Start() { _engine.Start(); Console.WriteLine("Car started."); } } |
3. ASP.NET Core 프로젝트 설정
ASP.NET Core 프로젝트를 설정하고 의존성을 등록합니다. 여기서 DI 컨테이너를 통해 인터페이스와 구현체를 매핑합니다.
Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class Startup { public void ConfigureServices(IServiceCollection services) { // IEngine 인터페이스와 GasolineEngine 구현체를 등록 services.AddScoped<IEngine, GasolineEngine>(); // ICar 인터페이스와 Car 구현체를 등록 services.AddScoped<ICar, Car>(); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } |
4. 의존성 주입을 받는 컨트롤러
DI 컨테이너를 통해 ICar
인터페이스를 주입받는 컨트롤러를 만듭니다.
CarController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using Microsoft.AspNetCore.Mvc; [ApiController] [Route("[controller]")] public class CarController : ControllerBase { private readonly ICar _car; public CarController(ICar car) { _car = car; } [HttpGet("start")] public IActionResult StartCar() { _car.Start(); return Ok("Car started."); } } |
5. 프로그램 실행
Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); } |
유지보수성의 예
요구사항 변경: 전기 엔진으로 변경
나중에 요구사항이 변경되어 자동차가 전기 엔진을 사용해야 한다고 가정합니다. 이 경우 코드의 수정은 매우 간단합니다.
변경된 Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class Startup { public void ConfigureServices(IServiceCollection services) { // IEngine 인터페이스와 ElectricEngine 구현체를 등록 services.AddScoped<IEngine, ElectricEngine>(); // 변경 부분 // ICar 인터페이스와 Car 구현체를 등록 services.AddScoped<ICar, Car>(); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } |
위의 코드는 IEngine
인터페이스의 구현체를 GasolineEngine
에서 ElectricEngine
으로 바꿨습니다. 이렇게 하면 나머지 코드는 전혀 수정할 필요가 없습니다.