애플리케이션 컨트롤러 - Application Controller

Application Controllers

설명

애플리케이션 컨트롤러는 도메인 논리를 프레젠테이션 계층(UI)에 표시하는 데 사용됩니다. 애플리케이션 컨트롤러는 DTO (Data Transfer Object)를 매개 변수로 사용하여 프리젠테이션 계층에서 사용됩니다. 또한 도메인 개체를 사용하여 특정 비즈니스 논리를 수행하고 DTO를 다시 프레젠테이션 계층으로 반환합니다. 따라서 프리젠테이션 계층은 도메인 계층에서 완전히 분리됩니다.

애플리케이션 컨트롤러 인터페이스

Axs에서 애플리케이션 컨트롤러는 IAppController 인터페이스를 구현해야 합니다. 프로그램 서비스에 대한 인터페이스를 만드는 것이 좋습니다.

먼저 애플리케이션 컨트롤러에 대한 인터페이스를 정의 해 보겠습니다 :

public interface ISampleAppController : IAppController
{
    bool Create(CreateSampleDto input);
    List<Sample> GetAll(GetAllSampleDto input);
    bool Update(UpdateSampleDto input);
    bool Delete(DeleteSampleDto input);
}

ISampleAppController에는 하나의 메서드 만 있습니다. 프레젠테이션 레이어에서 새로운 샘플을 만드는 데 사용됩니다. CreateSampleDto은 아래와 같이 DTO 개체입니다

// Create dto
public class CreateSampleDto
{
    [Required]
    public string Name { get; set; }

    public string ReceiptName { get; set; }
}

// Update dto
public class UpdateSampleDto
{
    [Required]
    public string Name { get; set; }

    public string ReceiptName { get; set; }
}

// Delete dto
public class DeleteSampleDto
{
    [Required]
    public string Name { get; set; }
}

이제 ISampleAppController를 구현할 수 있습니다 :

public class SampleAppController : ISampleAppController
{
    private readonly IRepository<Sample> _sampleRepository;

    // Sample의 레파지토리를 DI객체로 가져옵니다.
    public SampleAppController(IRepository<Sample> sampleRepository)
    {
        _sampleRepository = sampleRepository;
    }

    public bool Create(CreateSampleDto input)
    {
        var sample = _sampleRepository.FirstOrDefault(p => p.ReceiptName == input.ReceiptName);
        if (sample != null)
        {
            throw new UserFriendlyException("등록된 영수증으로 검색되지 않았습니다.");
        }

        sample = new Sample { Name = input.Name, ReceiptName = input.ReceiptName };
        _sampleRepository.Insert(sample);

        return true;
    }

    public bool Update(UpdateSampleDto input)
    {
        ...
    }

    public bool Delete(DeleteSampleDto input)
    {
        ...
    }

    public List<Sample> GetAll(GetAllSampleDto input)
    {
        ...
    }
}

여기에서 고려해야 할 몇 가지 중요한 사항이 있습니다 :

  • SampleAppController는 IRepository<Sample>을 사용하여 데이터베이스 작업을 수행합니다. 생성자 주입 패턴을 사용하므로 종속성 주입(dependency injection)을 사용합니다.

  • SampleAppController는 IAppController를 구현합니다. Axs에 의해 Dependency Injection 시스템에 자동으로 등록되며 다른 클래스에서 주입하여 사용할 수 있습니다. 여기서 명명 규칙이 중요합니다. 자세한 내용은 종속성 주입(dependency injection) 문서를 참조하세요.

  • CreateSample 메서드는 CreateSampleDto을 가져옵니다. 입력 DTO이며 Axs에 의해 자동으로 유효성 검사가 됩니다.

AppController 클래스

애플리케이션 컨트롤러는 위에서 선언 한대로 IAppController 인터페이스를 구현해야합니다. 선택적으로 AppController 기본 클래스에서 파생 될 수 있습니다.

AppController 클래스에는 로깅, 지역화 등을 쉽게 수행 할 수 있는 몇 가지 기본 기능이 있습니다. AppController 클래스를 확장하는 응용 프로그램 서비스에 대한 특수 기본 클래스를 만드는 것이 좋습니다. 이렇게하면 모든 애플리케이션 컨트롤러에 대해 몇 가지 공통 기능을 추가 할 수 있습니다. 샘플 애플리케이션 컨트롤러 클래스는 다음과 같습니다 :

public class VitaAppController : AppController, IVitaAppController
{
    public void CreateVita(CreateVitaDto input)
    {
        //TODO: 데이터 베이스 작업
    }
}

생성자에서 LocalizationSourceName을 정의하는 기본 클래스를 가질 수 있습니다. 이렇게하면 모든 서비스 클래스에 대해 반복하지 않습니다. 이 주제에 대한 자세한 정보는 로깅(logging) 및 현지화(localization) 문서를 참조하십시오.

Application Controllers 수정

목록 가져오기

애플리케이션 컨트롤러는 선택적 정렬 및 페이징 매개 변수를 제공하는 GetAll 메서드에 대한 인수로 PagedResultRequestDto를 기본값으로 가져옵니다. GetAll 메서드에 대한 다른 매개 변수를 추가 할 수도 있습니다. 예를 들어 사용자 지정 필터를 추가 할 수 있습니다. 이 경우 GetAll 메서드에 대한 DTO를 만들 수 있습니다.

public class GetAllVitasDto : PagedResultRequestDto
{
    public VitaState? State { get; set; }
}

여기서는 PagedResultRequestDto에서 상속합니다. 필수는 아니지만 원하는 경우 기본 클래스에서 페이징 및 정렬 매개 변수를 사용할 수 있습니다. 또한 상태별로 작업을 필터링하기 위해 선택적 State 속성을 추가했습니다. 이를 통해 사용자 지정 필터를 적용하기 위해 VitaAppController 클래스를 변경합니다 :

public class VitaAppController : AsyncAppController<Vita, VitaDto, int, GetAllVitasDto>
{
    public VitaAppController(IRepository<Vita> repository)
        : base(repository) { }

    protected override IQueryable<Vita> CreateQueryable(GetAllVitasDto input)
    {
        return base.CreateQueryable(input)
            .WhereIf(input.State.HasValue, t => t.State == input.State.Value);
    }
}

먼저 AsyncAppController 클래스에 네 번째 일반 매개 변수로 GetAllVitasDto을 추가했습니다 (세 번째는 엔티티의 PK 유형입니다). 그런 다음 CreateQueryable 메서드를 재정의하여 사용자 지정 필터를 적용합니다. 이 메서드는 AsyncAppController 클래스의 확장 클래스입니다. WhereIf는 조건부 필터링을 단순화하기 위한 Axs의 확장 방법입니다. 여기서 우리가 하는 일은 단순히 IQueryable을 필터링하는 것입니다.

생성 및 업데이트

실제 응용 프로그램에 적합하지 않을 수있는 작업을 가져오고, 만들고 수정하는 데 동일한 DTO (VitaDto)를 사용하고 있으므로 DTO 만들기 및 수정를 사용자 정의 할 수 있습니다.

CreateVitaDto 클래스를 생성하여 시작하겠습니다 :

[AutoMapTo(typeof(Vita))]
public class CreateVitaDto
{
    [Required]
    [StringLength(Vita.MaxTitleLength)]
    public string Title { get; set; }

    [StringLength(Vita.MaxDescriptionLength)]
    public string Description { get; set; }

    public Guid? AssignedSampleId { get; set; }
}

이 외에도 UpdateVitaDto DTO를 만듭니다 :

[AutoMapTo(typeof(Vita))]
public class UpdateVitaDto : CreateVitaDto, IEntityDto
{
    public int Id { get; set; }

    public VitaState State { get; set; }
}

여기에서는 CreateVitaDto에서 상속하여 수정 작업에 대한 모든 속성을 포함합니다 (다른 것을 원할 수 있음). IEntity (또는 int와 다른 PK에 대한 IEntity<PrimaryKey>)를 구현해야합니다. 수정중인 엔터티를 알아야하기 때문입니다. 마지막으로 CreateVitaDto에 없는 추가 속성 State를 추가했습니다.

이제 이러한 DTO 클래스를 AsyncAppController 클래스의 일반 인수로 사용할 수 있습니다 :

public class VitaAppController : AsyncAppController<Vita, VitaDto, int, GetAllVitasDto, CreateVitaDto, UpdateVitaDto>
{
    public VitaAppController(IRepository<Vita> repository)
        : base(repository)
    {

    }

    protected override IQueryable<Vita> CreateQueryable(GetAllVitasDto input)
    {
        return base.CreateQueryable(input)
            .WhereIf(input.State.HasValue, t => t.State == input.State.Value);
    }
}

확인

스웨거에서 확인하기

SampleAppController를 통한 확인

SampleProductAppController를 통한 확인

Last updated