태그 보관물: .net

선언적 코드를 사용한 ASP.NET Web API 데이터 검사

일반적으로 선언적(declarative) 코드는 명령형 코드에 비헤 가독성이 높고 테스트하기 쉬우며 코드의 양도 더 적습니다. System.ComponentModel.DataAnnotations 네임스페이스는 데이터를 검사하는 ValidationAttribute 하위 특성(attributes) 집합을 제공하며 이 특성들을 사용하면 데이터의 유효성을 검증하는 코드를 선언적으로 작성할 수 있습니다. ASP.NET Web API 액션 메서드에서도 이 특성들을 사용해 입력 데이터의 유효성을 검사할 수 있습니다.

계속 읽기

광고

Java의 함수형 프로그래밍이 생각보다 위험하지 않은 이유

어제 집에서 빈둥거리던 중 Why Functional Programming in Java is Dangerous란 제목의 글을 읽었습니다. 이글은 다음과 같은 Clojure 코드를 Java로 구현하면 OutOfMemeryError 혹은 StackOverflowError의 재앙이 닥칠 것이라 경고하고 있습니다.

(take 25 (squares-of (integers)))

하지만 이것은 사실이 아닙니다. Java는 분명 함수형 언어가 아니지만 저 글에서 언급한 재앙 없이 위 코드를 충분히 구현할 수 있습니다. Java에게서 억울한 누명을 벗겨주고 싶은 생각에 이 포스트를 작성합니다. 제목도 “Java의 함수형 프로그래밍이 생각보다 위험하지 않은 이유”라고 지어봤습니다. 🙂

계속 읽기

*오류 수정* C++와 C#, Java, 그리고 Node.js 정렬 성능 비교

조종국님께서 댓글에서 지적해주신 절사평균 오류가 수정되어 소스코드와 측정 결과가 업데이트되었습니다. 결과적으로 C# 이외의 언어들에 대한 정렬 성능 평가가 낮아졌습니다.
– 2014년 10월 17일 –

어제(2014년 6월 16일) 추가된 Java 코드가 공정하지 못했습니다. 예상보다 Java 코드가 느려서 검토해본 결과, 기존의 C++, C#, Node.js는 모두 rand() 네이티브 함수를 사용해 난수를 만들었기 때문에 난수 도메인의 크기가 15비트인 반면 Java 코드는 매개변수 없는 버전의 java.util.Random.nextInt() 함수를 사용했습니다. 이 포스트의 관심사는 언어별 정렬 속도가 아닌 최대한 유사한 코드를 이용한 CPU 집약적인 코드의 성능 비교이기 때문에 Java 역시 15비트 난수를 사용하도록 수정했습니다. 결과는 많이 달라졌습니다. 이것과 관련되어 수정된 부분은 별도 표시했습니다.
– 2014년 6월 17일 –

처음엔 귀찮아서 제외했지만 찝찝한 느낌이 사라지지 않아 Java를 추가했습니다.
– 2014년 6월 16일 –

며칠전 Swift의 -Ofast 컴파일러 설정에 대한 글을 접했습니다. 저는 아직 Swift에 대해 잘 모르고 실습 경험도 전혀 없지만 이 글에 의하면 -Ofast 설정은 약간은 도박적으로 코드의 제한을 풀어 성능을 극대화합니다. 결과적으로 정렬 작업에 대해 C 코드보다 약간 높은 성능을 보여준다고 하네요. 안정성을 담보로 하기 때문에 개발자의 주의를 강하게 요구하면서도 최소한의 성능 집약적 코드를 최적화하는 데에 이용 가치가 있을 수도 있겠습니다.

그렇다면 안정적 코드를 제공하는 ‘관리’ 개념을 가진 .NET 코드와 Java 코드는 어느 정도 성능을 보여주는지 C++ 코드와 비교해봤고 기왕 하는김에 성능 미신이 따라다니는 Node.js를 포함해 봤습니다.

계속 읽기

Microsoft.Owin.Testing 패키지를 이용한 인메모리 통합 테스트

단위 테스트 만큼이나 통합 테스트는 필요하며 통합 테스트에 있어서도 자동화는 중요합니다. 단위 테스트를 통과한 모듈도 서로 조합되면 운영 환경에서 오류를 발생시킬 가능성이 존재하며 다양한 이유로 인해 단위 테스트가 어려운 코드도 있죠. GUI를 가진 응용프로그램을 인력 자원을 동원해 하나하나 통합 테스트하거나 그것조차 제대로 하지 않는 것이 국내 사정이지만 CUIT(Code UI Tests)나 Jasmine 등의 E2E(End-to-End) 도구를 사용해 통합 테스트를 자동화하면 테스트 비용과 테스트 오류 가능성을 낮출 수 있습니다.

API 역시 통합 테스트 대상입니다. API는 GUI 기반 응용프로그램과 비교할 때 통합 테스트를 수동으로 진행하기에 귀찮고 어려운 반면 자동화하기는 더 쉽습니다. Jasmine을 이용한 API 통합 테스트 자동화를 고려해 볼 수도 있지만 Visual Studio에 의해 관리되고 있는 기존의 테스트가 있다면 동일한 테스트 도구를 통해 관리하는 것이 훨씬 좋겠죠.

Microsoft.Owin.Testing 패키지를 사용하면 OWIN(Open Web Interface for .NET) 기반 ASP.NET Web API에 대한 통합 테스트를 쉽게 작성할 수 있습니다. 테스트는 메모리를 통해 이루어지기 때문에 네트워크 트래픽이 발생하지 않아 매우 효율적이면서도 ASP.NET Web API의 전체 파이프라인을 관통합니다. 뿐만 아니라 IoC 컨테이너를 조작하면 컨트롤러 이후의 과정을 모의화하는 것도 가능합니다.

계속 읽기

Repository and Unit of Work 디자인 패턴을 이용한 TDD(Test-driven Development)

다중 계층 아키텍처는 관심사 분리(SoC, Separation of Concerns) 원칙 구현의 하나로, 각 계층은 전체 프로세스 흐름 중 담당하는 작업에만 집중하여 프로그램 코드의 복잡도를 낮출 수 있습니다. 하지만 계층간 결합도가 높다면 여전히 낮은 테스트성(testability)으로 인해 단위 테스트와 테스트 주도 개발(TDD, Test-driven Development), 행위 주도 개발(BDD, Behavior-driven Development) 등의 방법을 적용하기 어렵습니다. 이 포스트의 주 목적은 비즈니스 논리에 대한 데이터베이스에 독립적인 단위 테스트를 작성하고 TDD를 적용하는 방법을 설명하는 것입니다.

계속 읽기

ASP.NET Identity 사용자 모델 확장

5/15/2014 추가 Microsoft ASP.NET Identity EntityFramework 패키지가 2.0.1 버전으로 업데이트 되었습니다. IdentityUser 클래스에 이메일 주소가 포함되었고 UserValidator 클래스를 사용해 이메일 주소 중복 여부를 검사할 수 있습니다.

사용자 모델

Microsoft ASP.NET Identity EntityFramework 패키지는 응용프로그램 사용자를 나타내는 IdentityUser 모델 클래스를 제공합니다. 최근의 ASP.NET 프로젝트 템플릿은 이 클래스와 EntityFramework을 사용해 개별 계정 관리를 구현합니다. 다음은 IdentityUser 클래스 정의입니다.

using Microsoft.AspNet.Identity;
using System;
using System.Collections.Generic;

namespace Microsoft.AspNet.Identity.EntityFramework
{
    public class IdentityUser : IUser
    {
        public IdentityUser();
        public IdentityUser(string userName);

        public virtual ICollection<IdentityUserClaim> Claims { get; }
        public virtual string Id { get; set; }
        public virtual ICollection<IdentityUserLogin> Logins { get; }
        public virtual string PasswordHash { get; set; }
        public virtual ICollection<IdentityUserRole> Roles { get; }
        public virtual string SecurityStamp { get; set; }
        public virtual string UserName { get; set; }
    }
}

제가 아쉬운 것은 모델에 이메일 주소가 포함되어 있지 않다는 점입니다. 사용자 계정 정보에 이메일 주소 속성을 추가하려면 조금 귀찮은 작업을 해줘야합니다. 이 포스트에서는 SPA(Single-Page Application) 프로젝트를 기준으로 사용자 모델을 확장하는 방법을 설명합니다. 계속 읽기

ASP.NET에서 JSON 정적 컨텐트 노출

현재 ASP.NET 웹 응용프로그램은 기본적으로 확장자가 json인 파일에 대한 MIME 맵이 설정되어있지 않습니다. 그래서 브라우저에서 JSON 정적 컨텐트에 접근하려하면 404.3 상태가 반환됩니다.

HTTP Error 404.3 - Not Found

The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.

이 문제는 웹 응용프로그램의 web.config 파일에 아래처럼 JSON 정적 컨텐트에 대한 설정을 추가하면 해결됩니다.

<system.webServer>
  <staticContent>
    <mimeMap fileExtension=".json" mimeType="application/json"/>
  </staticContent>
</system.webServer>