본문 바로가기
Backend/C# .NET

[ASP.NET] 개요 / MVC 패턴 / 의존성 주입 패턴

by SOLYI 2021. 12. 7.
  • 닷넷 코어는 패턴 프로그래밍에 최적화 되어있다.
  • 패턴 ? 사용자에게 보다 나은 서비스를 제공
  • 프로그램 개발 ? 테스트와 유지보수가 쉬워야 한다.
  • 애플리케이션의 존재 목적 ? 사용자를 만족시키는것

 

  • 닷넷코어는 아래 2가지를 사용한다
    • MVC 패턴 (Model-View-Controller)
    • 의존성 주입 패턴 (Dependency Injection)

2021-12-07

 

  • MVC 패턴(Model-View-Controller)
    • MVC 프로젝트 생성
    • C - MembershipController 컨트롤러 폴더에 추가 
      • public IActionResult Login(LoginInfo login) {} 생성
      • 내용에는 if문 내부에서 ModelState.IsValid 를 확인
      • if문으로 ID, PW가 일치하는지 확인하고
      • 일치하는 경우 TempData["Message"] 로 문구 지정, return RedirectAction("index", "Membership")
      • 일치하지 않으면 로그인 실패 메세지 출력
    • M - LoginInfo 모델 폴더에 추가
      • [Required(ErrorMessage = "사용자 아이디를 입력하세요")]
        [MinLength(6, ErrorMessage = "사용자 아이디는 6글자 이상 입력하세요")]
        [System.ComponentModel.DataAnnotations.Display(Name = "사용자 아이디")]
        public string? UserID { get; set; }
      • 패스워드도 동일하게 추가 해준다.
    • V - Login 뷰 폴더에 추가
      • @model LoginInfo
        @{
            ViewData["Title"] = "멤버십 로그인";
            Layout = "~/Views/Shared/_Layout.cshtml";
        }
        
        <h2>@ViewData["Title"]</h2>
        
        <div class="row">
            <div class="col-md-4">
                <form method="post" asp-controller="Membership" asp-action="Login" onsubmit="btnLogin.disabled = true; return true;">
                    <div class="text-danger" asp-validation-summary="All"></div>
                    <div class="form-group">
                        @Html.DisplayNameFor(m => m.UserID)
                        <input type="text" class="form-control" asp-for="UserID" placeholder="user id" autofocus>
                        <span class="text-danger" asp-validation-for="UserID"></span>
                    </div>
                    <div class="form-group">
                        @Html.DisplayNameFor(m => m.Password)
                        <input type="password" class="form-control" asp-for="Password" placeholder="password"/>
                        <span class="text-danger" asp-validation-for="UserID"></span>
                    </div>
                    <button type="submit" name="btnLogin" class="btn btn-lg btn-success btn-block">멤버십 로그인</button>
                </form>
            </div>
        </div>
  • F5로 실행 후, localhost:xxxx/Mebership/Login 로 접속하면 이렇게 화면이 나온다.
  • 그리고 모델 LoginInfo 에서 설정한 MinLength 6을 충족하지 않으면 다음과 같이 표시 된다.
  • 마지막으로 로그인에 성공한다면 index 뷰 페이지로 이동!

 

  • 좀 더 기본 개념부터 배울줄 알았는데 무작정 프로젝트를 생성하고, MVC 패턴을 이용한 프로젝트를 만들어서 당황스러웠다. 잘 되고있는건지도 모른채 강사님의 타이핑을 따라하려니 긴가민가 상태로 타이핑 연습..!
  • 처음부터 JAVA로 개발을 시작했고 JAVA에 익숙해져있어서 생소하지만, JSP 보다 ASP가 배우기 쉽다는 말을 믿고 따라해본다.
  • 또한, 이클립스와 VSCode에 익숙해져있던 나에게 Visual Studio는 너무 무겁게 느껴진다..  이클립스에선 ctrl + space로, VSCode에선 코드를 쓰면 자동으로 완성이 되곤 했는데... VS에선 tap을 누르라는 등의 문구가 뜬다.. 어색하고 반응이 넘넘 느림.
  • [Required] 나 [MinLength] 와 같이 자바에는 없던 개념이 생소하게 느껴진다. 하지만 익숙해지면 편리할듯!!!?!
  • getter, setter 기능의 코드를 직접 추가하지 않고 public string? UserId { get; set; } 이렇게 한줄로 사용이 가능한 점이 신기하다.
  • View페이지는 확장자가  .cshtml 씨샵..html..? ㅎ 뭐지
  • 부트스트랩을 따로 적용한적 없는데 자동으로 들어있는건지 뭔지, class로 부트스트랩에서 사용하던것들을 추가해주니 자동으로 적용이 되어있었다! (신기!)
  • input 태그와 단짝 친구였던 <label>을 따로 작성하지 않고 이걸로 나타냈다. 
    • @Html.DisplayNameFor(m => m.UserID)
    • 강사님, 갑자기 람다식이라고 하셔도, 그게 뭔데요
  • 처음 해보는것들이라 다 생소하고, 일단 Visual studio 가 적응이 안되지만... 재밌네

 

 


2021-12-08

  • 의존성 주입 패턴(Dependency Injection
  • NetCore.Services 라는 이름의 새 프로젝트(클래스 라이브러리) 를 생성한다.
    • Interfaces와 Svcs 폴더 각각 생성 한 뒤 인터페이스 IUser.cs , 서비스 UserService.cs 작성
    • UserService에  private IEnumerable<User> GetUserInfos(){ } 추가
  • NetCore.data 라는 이름의 새 프로젝트(클래스 라이브러리)를 생성한다.
    • DataModels와 ViewModels 폴더 각각 생성한다.
    • 이전 시간에 생성한 Models/LoginInfo.cs 파일을 ViewModels 폴더로 복사한다
    • namespace 부분을 NetCore.Data.ViewModels  로 변경한다.
      • (자바의 패키지 개념 같다!)
    • DataModels/User.cs 파일을 생성 한 뒤 UserID, UserName, UserEmail, Password, JoinedUtcDate 변수를 생성하고 get; set;
  • NetCore.Services - 종속성 - 우클릭 - [프로젝트 참조 추가] 를 클릭하여 연결해준다.
  • Svcs/UserService.cs  내부에서 빨간 밑줄이 그어져있던 <User> 부분을 클릭하여 using 추가
    • GetUserInfos(), checkTheUserInfo() 를 추가해준다
    • 내부에 코드를 작성하고 위에 #resion private methods 끝에 #endrigion 을 추가해준다 (내부적으로만 사용한다는 의미)
    • 코드
      • namespace NetCore.Services.Svcs
        {
            public class UserService
            {
                #region private methods
                private IEnumerable<User> GetUserInfos()
                {
                    return new List<User>()
                    {
                        new User()
                        {
                            UserID = "solyi",
                            UserName = "최솔이",
                            UserEmail = "choi-solyi@naver.com",
                            Password = "123456"
                        }
                    };
                }
                private bool checkTheUserInfo(string userId, string password)
                {
                    return GetUserInfos().Where(u => u.UserID.Equals(userId) && u.Password.Equals(password)).Any();
                }
                #endregion
            }
        }
  • Interfaces/IUser.cs 파일로 와서 bool MatchTheUserInfo(LoginInfo login); 추가 
    • 당연하게도 using을 사용해서 참조를 추가해준다.
  • 다시 Svcs/UserService.cs 로 돌아와 public class UserService 뒷부분에 : IUser 을 추가하여 상속 받는다.
    • 인터페이스를 상속 받았으므로 빨간 밑줄이 뜨면 alt + enter 로 명시적으로 인터페이스를 구현 해준다.
    • return 으로는 checkTheUserInfo(login.UserID, login.Password);
  • 지난 시간에 작성한 MembershipController에서
    • if (login.UserID.Equals(userId) && login.Password.Equals(password)) 부분을 삭제 한뒤
    • if( 여기 )를 새로 작성하려한다.
    • 인터페이스 IUser  를 사용하기위해 종속성 - 우클릭 - [프로젝트 참조 추가] - NetCore.Services 선택 확인
    • private IUser _user = new UserService(); 추가
    • 윗줄의 if문에 _user.MatchTheUserInfo(login) 를 추가.
  • NetCore.Web 프로젝트에는 NetCore.Data 프로젝트를 를 참조 추가하지 않았는데 사용 가능한 이유는
    • Web 프로젝트는 Services 프로젝트를 참조하고 있고,
    • Sevices 프로젝트는 Data 프로젝트를 참조하고 있기 때문이다.
  • 코드 위쪽에서 우클릭 - 뷰로 이동해보면 LoginInfo 참조가 풀려 빨간 밑줄이 생겼다.
    • @using NetCore.Data.ViewModels  를 추가 해야하지만 매번, 모든 페이지에 작성 할 수 없기 때문에
    • views/_ViewImports.cshtml 에서 공통으로 참조하는 내용을 추가 할수 있다.
  • 공통 레이아웃은 Views/Shared/_Layout.cshtml 파일이다. 내부에서 사용하지 않던 privacy 메뉴를 바꿔 주었다.
    • <a class="nav-link text-dark" asp-area="" asp-controller="Membership" asp-action="Index">멤버십</a>
      <a class="nav-link text-dark" asp-area="" asp-controller="Membership" asp-action="Login">멤버십 로그인</a>
  • 하지만 문제가 발생....
    • 문제1: Visual Studio 2022가 너무 무거워서 Visual Studio 2019를 새로 설치 한 후 이전 강의의 프로젝트를 그대로 가져와 사용했는데, 버전이 달라서 빌드에 실패했다. 이전에 성공한 빌드를 실행하냐고 자꾸 나옴 ㅠㅠ 그래서 Layout.cshtml 파일에서 Privacy 메뉴부분을 삭제했는데도 불구하고 자꾸 나왔다.
    • 해결1: 2019에서는 지원하지 않는 버전의 무언가가.. 있는것 같아서 2022 버전을 실행하니 해결이 되었다.
    • 문제2: userId, name, email.. 등 하드코딩 해둔 부분이 어딨는지 몰라서 한참 헤맸다.
    • 해결2: UserServices에 적어놨는데 #region 부분이 닫혀있어서 안보였다....ㅠㅠ 헷갈린다
  • 실행은 성공적이었다.
  • 이제 의존성 주입 방식으로 전환해보려 한다.
  • 의존성 주입 방식 - 생성자 주입  
    • MembershipController 에서  private IUser _user = new UserService(); 부분을 변경한다.
              private IUser _user;
      
              public MembershipController(IUser user)
              {
                  _user = user;
              }
    • 어... 그리고 프로젝트 제일 하단에 Startup.cs 에서 코드를 추가하라는데 나는 이 파일이 없다 .....ㅠㅠ....
    • 밑에 해결 방안씀 ..
    • // Startup.cs 파일 내부
      ...
      public void ConfigureServices( ~ ) {
        services.AddScoped<IUser, UserService>();
        // 윗줄 추가!!!  빨간줄은 using 추가해주기..
        services.AddMvc(); 
      }
    • IUser인터페이스 (껍데기)에  UserService 클래스 인스턴스(내용)를 주입한다는 코드.
      •  의존성 주입을 사용하기 이용하기 위해 서비스로 등록한다.
      • 아래의 AddMvc(); 는 MVC패턴을 사용하기 위해서 서비스로 등록한것.
    • 버전이 업그레이드 되면서 일일이 추가해주지 않아도 자동으로(^^) 추가 되지 않을까 해서 추가해봤는데 역시나 에러 메세지 발생. ㅎㅎ ㅠㅠ 
  • 정리! 
    • 닷넷코어는 두가지 패턴이 존재한다
      • MVC 패턴 - 각자 맡은 역할을 다하도록 분리 되어있음.
      • 의존성 주입 - 클래스 인스턴스를 직접 받지 않고, 생성자의 파라미터를 통해 주입받아 사용된다.
    • 닷넷코어의 키워드는 "분리"
  • 오늘의.. 느낀점..
    • asp.net 분명 배우기 쉽다고 했는데.... 왜이리 헷갈릴까 java랑 섞여서 그럴까..? 아예 제로베이스였다면 어땠을지 모르겠다... 는 그럴리가 없다. MVC 패턴도 의존성 주입도 개념을 알고 있는 상태여서 이정도로 끝난게 아닐까?ㅎ 기본 개념도 없었다면 안된다고 금방 때려쳤을지도.
    • Visual Studio 2022 버전이 넘 무거운듯 하여 2019 버전으로 바꿔서 진행해봤는데 역시 신버전에서 구버전으로 가는거라 그런지 여러가지 문제가 발생했다. 현업에서 버전 맞추는걸 중요시 하는 이유를 알거같다.
    • Java가 지금 익숙해서 그렇지... 아예 개념이 없었으면 Interface고 종속성이고 참조고 뭐고 아예 몰랐을것같다.
    • 이제 ASP.NET Core 개요 파트가 끝났으니 내일부터는 Entity Framework core 파트에 들어간다. 
    • Entity framework core 개요, Code-First 방식, Unique Index 지정, Database-First 방식 등등 또 또또 생소한, 모르는 단어들 대거 등장^^ 
    • 실무 들어가기 전에 예습할수있는 시간이 있다는것에 감사하쟈 .. .

 

반응형