login register Sysop! about ME  
qrcode
    최초 작성일 :    2016년 09월 21일
  최종 수정일 :    2016년 09월 21일
  작성자 :    soggun
  편집자 :    soggun (송원석)
  읽음수 :    12,220

강좌 목록으로 돌아가기

필자의 잡담~

이번 문서는 ASP.NET Core MVC 기본개념 파트의 View 섹션 중 View에서 종속성 주입을 사용하는 방법을 설명하고 있습니다.

모든 컬럼은 http://docs.asp.net의 내용을 참고하여 번역한 것입니다. Windows 뿐만 아니라 Linxu, OS X에서도 동작하는 완전한 크로스 플랫폼 서버기술인 ASP.NET Core! 기대해 주세요.

본 번역문서는 개인적인 취지로 번역되어 제공되는 문서로, 원문을 비롯한 모든 저작권은 마이크로소프트사에 있습니다. 마이크로소프트사의 요청이 있을 경우, 언제라도 게시가 중단될 수 있습니다. 본 번역문서에는 오역이 포함되어 있을 수 있으며 주석도 번역자 개인의 견해일뿐입니다. 마이크로소프트사는 본 문서의 번역된 내용에 대해 일체의 보장을 하지 않습니다. 번역이 완료된 뒤에도 제품이 업그레이드 되거나 기능이 변경됨에 따라 원문도 변경되거나 보완되었을 수 있으므로 참고하시기 바랍니다.

원문: https://docs.asp.net/en/latest/mvc/views/dependency-injection.html

뷰에 서비스 주입하기

ASP.NET Core MVC는 뷰에 대한 의존성 주입(Dependency Injection)을 지원합니다. 이 기능은 지역화(Localization)나 뷰의 요소를 구성하기 위해서 전용 데이터가 필요한 경우 같은 뷰 전용 서비스에 유용하게 활용할 수 있습니다. 그러나 여전히 컨트롤러와 뷰 간에 관심사의 분리(Separation of Concerns)를 유지하기 위해서 최대한 노력해야 하므로, 뷰에서 출력하는 주요 업무 데이터는 그대로 컨트롤러에서 전달하는 것이 바람직합니다.

목차:

간단한 예제

뷰에 서비스를 주입하려면 @inject 지시문을 사용하면 됩니다. @inject 지시문으로 뷰에 속성을 추가한 다음, DI를 이용해서 그 속성을 채운다고 생각하면 이해가 빠를 것입니다.

@inject 지시문의 구문은 다음과 같습니다:

@inject <type> <name>

다음은 실제 @inject 지시문의 사용 예입니다:

@using System.Threading.Tasks
@using ViewInjectSample.Model
@using ViewInjectSample.Model.Services
@model IEnumerable<ToDoItem>
@inject StatisticsService StatsService
<!DOCTYPE html>
<html>
<head>
  <title>To Do Items</title>
</head>
<body>
  <div>
    <h1>To Do Items</h1>
    <ul>
      <li>Total Items: @StatsService.GetCount()</li>
      <li>Completed: @StatsService.GetCompletedCount()</li>
      <li>Avg. Priority: @StatsService.GetAveragePriority()</li>
    </ul>
    <table>
      <tr>
        <th>Name</th>
        <th>Priority</th>
        <th>Is Done?</th>
      </tr>
      @foreach (var item in Model)
            {
          <tr>
            <td>@item.Name</td>
            <td>@item.Priority</td>
            <td>@item.IsDone</td>
          </tr>
      }
    </table>
  </div>
</body>
</html>

이 뷰에는 전반적인 통계를 보여주는 요약 정보와 ToDoItem 인스턴스의 목록이 함께 출력됩니다. 이때, 필요한 요약 정보를 뷰에 주입한 StatisticsService에서 가져오는데, 이 서비스는 Startup.cs 파일의 ConfigureServices 메서드에서 의존성 주입에 등록됩니다:

// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddTransient<IToDoItemRepository, ToDoItemRepository>();
    services.AddTransient<StatisticsService>();
    services.AddTransient<ProfileOptionsService>();

그리고 StatisticsService 클래스는 리파지터리를 통해서 접근해서 가져온 ToDoItem 인스턴스 집합을 대상으로 몇 가지 계산을 수행합니다.

using System.Linq;
using ViewInjectSample.Interfaces;
 
namespace ViewInjectSample.Model.Services
{
    public class StatisticsService
    {
        private readonly IToDoItemRepository _toDoItemRepository;
 
        public StatisticsService(IToDoItemRepository toDoItemRepository)
        {
            _toDoItemRepository = toDoItemRepository;
        }
 
        public int GetCount()
        {
            return _toDoItemRepository.List().Count();
        }
 
        public int GetCompletedCount()
        {
            return _toDoItemRepository.List().Count(x => x.IsDone);
        }
 
        public double GetAveragePriority()
        {
            if (_toDoItemRepository.List().Count() == 0)
            {
                return 0.0;
            }
 
            return _toDoItemRepository.List().Average(x => x.Priority);
        }
    }
 }

본문의 예제 리파지터리는 메모리에 저장된 컬렉션을 사용하고 있습니다. 그러나 이 예제에 사용된 구현 방식은 (모든 데이터를 메모리에 올려 놓고 작업하는 방식은) 원격으로 접근하는 대량의 데이터 집합을 대상으로는 권장되지 않습니다.

이번 예제는 뷰에 바인딩 된 모델의 데이터와 뷰에 삽입된 서비스의 데이터를 함께 출력합니다:

조회 데이터 채우기

뷰 주입은 드롭다운 리스트 같은 UI 요소의 옵션을 채워야 할 때 유용합니다. 가령, 성별과 상태 및 기타 설정을 지정할 수 있는 옵션들을 제공하는 사용자 프로필 폼을 가정해보시기 바랍니다. 일반적인 MVC 접근방식으로 이런 폼을 렌더하기 위해서는 컨트롤러에서 이런 옵션 집합들 각각에 대한 데이터 접근 서비스를 요청한 다음, 바운드 될 각각의 옵션 집합을 모델이나 ViewBag에 채워넣어야 합니다.

다른 접근방식은 뷰에 직접 서비스를 주입해서 옵션들을 가져오는 것입니다. 이 방법은 컨트롤러 구현에 필요한 코드의 양을 최소화시켜주고, 뷰 요소 구성을 위한 로직을 뷰 자체로 이동시켜줍니다. 결과적으로 사용자 프로필 편집 폼을 출력하는 컨트롤러 액션에서는 사용자 프로필의 인스턴스만 뷰에 전달하면 됩니다:

using Microsoft.AspNetCore.Mvc;
using ViewInjectSample.Model;
 
namespace ViewInjectSample.Controllers
{
    public class ProfileController : Controller
    {
        [Route("Profile")]
        public IActionResult Index()
        {
            // TODO: look up profile based on logged-in user
            var profile = new Profile()
            {
                Name = "Steve",
                FavColor = "Blue",
                Gender = "Male",
                State = new State("Ohio""OH")
            };
            return View(profile);
        }
    }
}

HTML 폼에서는 이 세 가지 속성들에 대한 드롭다운 리스트 등을 이용해서 프로필 설정을 수정합니다:

그리고 드롭다운 리스트들의 목록은 뷰에 주입된 서비스를 이용해서 채워집니다:

@using System.Threading.Tasks
@using ViewInjectSample.Model.Services
@model ViewInjectSample.Model.Profile
@inject ProfileOptionsService Options
<!DOCTYPE html>
<html>
<head>
  <title>Update Profile</title>
</head>
<body>
  <div>
    <h1>Update Profile</h1>
    Name: @Html.TextBoxFor(m => m.Name)
    <br />
    Gender: @Html.DropDownList("Gender",
           Options.ListGenders().Select(g =>
                new SelectListItem() { Text = g, Value = g }))
    <br />
 
    State: @Html.DropDownListFor(m => m.State.Code,
           Options.ListStates().Select(s =>
                new SelectListItem() { Text = s.Name, Value = s.Code }))>
    <br />
 
    Fav. Color: @Html.DropDownList("FavColor",
           Options.ListColors().Select(c =>
                new SelectListItem() { Text = c, Value = c }))
  </div>
</body>
</html>

ProfileOptionsService 클래스는 이 폼에 필요한 데이터만을 제공하기 위해서 전용으로 설계된 UI 수준의 서비스입니다:

using System.Collections.Generic;
 
namespace ViewInjectSample.Model.Services
{
    public class ProfileOptionsService
    {
        public List<string> ListGenders()
        {
            // keeping this simple
            return new List<string>() { "Female""Male" };
        }
 
        public List<State> ListStates()
        {
            // a few states from USA
            return new List<State>()
            {
                new State("Alabama""AL"),
                new State("Alaska""AK"),
                new State("Ohio""OH")
            };
        }
 
        public List<string> ListColors()
        {
            return new List<string>() { "Blue""Green""Red""Yellow" };
        }
    }
 
    public class State
    {
    }
}

: 먼저 사용할 형식을 Startup.cs 파일의 ConfigureServices 메서드에서 의존성 주입을 통해서 등록해야 한다는 점을 잊지 마십시오.

서비스 재정의하기

이 기법을 활용하면 새로운 서비스를 주입하는 작업 외에 기존에 페이지에 주입된 서비스를 대체할 수도 있습니다. 다음 그림은 첫 번째 예제에 사용된 페이지에서 사용 가능한 모든 필드들을 보여줍니다:

직접 확인할 수 있는 것처럼 기본 필드로 Html, Component, 그리고 Url이 포함되어 있습니다 (주입된 StatsService 뿐만 아니라). 만약 기본 HTML 헬퍼의 인스턴스를 직접 구현한 버전으로 대체하고 싶다면, 다음과 같이 @inject 지시문을 이용해서 손쉽게 처리할 수 있습니다:

@using System.Threading.Tasks
@using ViewInjectSample.Helpers
@inject MyHtmlHelper Html
<!DOCTYPE html>
<html>
<head>
  <title>My Helper</title>
</head>
<body>
  <div>
    Test: @Html.Value
  </div>
</body>
</html>

기존 서비스를 확장하고 싶은 경우, 기존 구현을 상속받거나 래핑해야 할 때 간단히 이 기법을 활용하면 됩니다.


authored by


 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})