DI (Dependency Injection) 디자인 패턴의 목표
종속성 주입 패턴은 골프에 비유할 수 있다.
고객이 클럽을 요청했을때, 훌륭한 캐디는 상황에 맞는 클럽을 전달해준다.
고객은 굳이 구체적인 클럽 이름을 알려줄 필요가 없다.
티샷을 날릴때는 WoodClub, 방향과 정확도에 집중할때는 IronClub, 그린 근처에서 온그린 할때는 WedgeClub, 그린에서 홀컵에 공을 넣을때는 PutterClub이라는 논리가 캐디 머리속에 있기 때문에, 고객은 단순히 클럽만 요구하면 된다.
유지보수 관점에서 DI의 장점을 알아보자!
코드속의 tight-coupling을 줄이고, 유지보수가 쉬워지도록 한다.
1. DI를 사용하지 않은 경우
Class1에서 Class2를 사용하는 경우, Class1은 Class2에 의존한다고 한다. Class1에서 Class2를 사용하기 위해서 new key를 사용하여 새로운 object를 선언한다.
작은 규모의 application이나 class가 많지 않은 경우 이렇게 사용해도 된다. 이렇게 사용하는 것을 Tight Coupled되었다고 한다. 더이상 Class2를 사용하지 않는 경우, Class2를 사용하는 모두 Class에서 Class2 -> Class3로 변경해야 한다.
많은 Class에서 사용하는 경우, 유지보수에 어려움이 있다.
2. DI를 사용하는 경우
Class1의 constructor에 interface2를 사용하면 Service Container에 Interface2와 매핑된 Class2라는 Concrete Class를 주입한다. Class2 -> Class3으로 변경하기 위해서는 Service Container의 매핑된 Class만 변경하면 된다.
Unity NuGet Package 설치
Install-Package Unity.Mvc3
설치 후, package.config 파일을 확인해보면 아래 소스가 추가된 것을 확인할 수 있다.
<package id="CommonServiceLocator" version="1.0" targetFramework="net45" />
<package id="Unity" version="2.1.505.0" targetFramework="net45" />
<package id="Unity.Mvc3" version="1.2" targetFramework="net45" />
Bootstrapper.cs 파일도 프로젝트에 자동으로 추가된다.
Global.asax.cs 에 Unity 등록
Application_Start() 함수에 Bootstrapper.Initialise(); 추가
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Bootstrapper.Initialise();
}
인터페이스와 클래스 만들기
BannerService.cs
interface는 별도의 cs파일을 만들어 분리하는 것이 좋다.
다른 데서 쓸 일이 없을 때는 같은 파일에 넣어도 무방하다.
public interface IBannerService
{
int Delete_Banner(int idx);
}
public class BannerService : IBannerService
{
#region 배너리스트 삭제하기
public int Delete_Banner(int idx)
{
DapperManager dm = new DapperManager(DB_StrName.DB);
return dm.DeleteRow(idx, "T_BANNER");
}
#endregion
}
Bootstrapper.cs 파일 BuildUnityContainer 함수에 의존성 주입 클래스 정의
container.RegisterType<IBannerService, BannerService>();
container에 IBannerService를 요청하면 BannerService instance를 반환한다.
전체소스
public static class Bootstrapper
{
public static void Initialise()
{
var container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
container.RegisterType<IBannerService, BannerService>();
// e.g. container.RegisterType<ITestService, TestService>();
return container;
}
}
요청이 끝나면, component는 IDisposable에 의해 적절히 dispose된다.
Controller에 주입
public class BannerController : BaseController
{
private IBannerService service;
public BannerController(IBannerService service)
{
this.service = service;
}
// POST: Banner/Delete/5
[HttpPost]
public JsonResult Delete(FormCollection collection)
{
try
{
// TODO: Add delete logic here
int bannerIdx = int.Parse(collection["bannerIdx"]);
Banner banner = service.Get_Banner(bannerIdx);
FileManager fileManager = new FileManager();
fileManager.FileDelete(banner.FileName, AttachFilePath.Banner_AttachedFilePath);
service.Delete_Banner(bannerIdx);
return Json(new { result = "ok" });
}
catch(Exception ex)
{
return Json(new { result = ex.Message });
}
}
}
동일한 interface를 여러 class에서 구현한 경우, 아래와 같이 사용 가능하다.
Bootstrapper.cs
container.RegisterType<IBannerService, WebBannerService>("Web");
container.RegisterType<IBannerService, MobileBannerService>("Mobile");
Service Injection에 name을 지정한다.
BannerController.cs
using Microsoft.Practices.Unity;
public class BannerController : BaseController
{
private IBannerService service;
public BannerController([Dependency("Mobile")] IBannerService service)
{
this.service = service;
}
}
Microsoft.Practices.Unity.DependencyAttribute를 사용하여 원하는 injection name을 지정할 수 있다.
'ASP.NET MVC' 카테고리의 다른 글
ASP.NET MVC] MVC에서 Vue .js 사용하기 (0) | 2022.01.07 |
---|---|
ASP.NET MVC] Vue.js 로 CRUD 구현 (0) | 2022.01.06 |
Visual Studio 2019] 디버깅 팁, Debugger Tips (0) | 2021.12.23 |
ASP.NET] DapperManager.cs (0) | 2021.12.22 |
ASP.NET] 로그인 체크, 접속권한 체크 (5) | 2021.12.21 |
댓글