2012-11-02 4 views
2

asp.net web api에서 모델 클래스에 IValidatableObject를 구현 중입니다. 일부 개체는 전체 유효성 검사를 수행하기 위해 데이터 리포지토리에 액세스해야합니다.asp.net web api 모델 클래스에 삽입 할 수 있습니까

IValidatableObject.Validate를 호출하기 전에 DAL 종속성을 해결할 수 있습니까? 아니면 Validate 호출의 종속성을 해결할 다른 방법이 있습니까?

Inject into asp.net web api model with autofac에 따라 autofac을 사용하려고하지만 모델이 종속성 해결 프로그램을 사용하여 호출되지 않은 것처럼 보입니다.

+1

이 기사에 관심이있는 것 같습니다. http://aspnetwebstack.codeplex.com/workitem/463이 기능이 실제로 구현되어야합니다. 그렇게한다면 투표 할 수 있습니다. – tugberk

답변

5

모델 클래스는 종속성 삽입의 일부가 아니어야합니다. 또한 그들 만의 유효성 검증을 책임 져야하지 않습니다 (유효성 검증 속성을 사용하여 그것들을 꾸미기도 - 단지 메타 데이터 일뿐입니다 - 괜찮을 것입니다).

대신 유효성 검사를 수행 할 적절한 추상화를 정의하십시오. 특정 유형의 IValidator<T> 인터페이스의 0, 1, 또는 여러 구현을 가질 수

public interface IValidator<T> 
{ 
    ValidationResult Validate(T instance); 
} 

이 방법, 당신은 Autofac 모든 꽤 효과적으로을 등록 할 수 있습니다 : 예를 들어,이 추상화를 정의합니다.

유형이 더 검증이없는 경우 컨테이너가 기본적으로 비어 있음 구현 다시 전달하도록 할 수 있습니다 : 당신이 복합에서 그들을 포장 수, 유형이 정의 된 여러 유효성 검사기가있는 경우

// Implementation of the Null Object pattern 
public class EmptyValidator<T> : IValidator<T> 
{ 
    public ValidationResult Validate(T instance) 
    { 
     return ValidationResult.ValidResult; 
    } 
} 

을 :

// Implementation of the Composite pattern 
public class CompositeValidator<T> : IValidator<T> 
{ 
    private readonly IEnumerable<Validator<T>> col; 

    public CompositeValidator(IEnumerable<Validator<T>> col) 
    { 
     this.col = col; 
    } 

    public ValidationResult Validate(T instance) 
    { 
     ValidationResult total = ValidationResult.ValidResult; 

     foreach (var validator in this.col) 
     { 
      var result = validator.Validate(instance); 
      total = ValidationResult.Append(total, result); 
     } 

     return total; 
    } 
} 

웹 API 컨트롤러에 IValidator<T>을 직접 삽입하는 대신 IRepository<T> 인터페이스를 둘러싸는 데코레이터를 만듭니다. 이렇게하면 리포지토리를 변경하지 않고도 유효성 검증 동작을 추가 할 수 있습니다. 이러한 구현은 다음과 같을 수 있습니다.

public class ValidationRepositoryDecorator<T> 
    : IRepository<T> 
{ 
    private readonly IRepository<T> decorated; 
    private readonly IValidator<T> validator; 

    public ValidationRepositoryDecorator(
     IRepository<T> decorated, 
     IValidator<T> validator) 
    { 
     this.decorated = decorated; 
     this.validator = validator; 
    } 

    public void Save(T instance) 
    { 
     var result = this.validator.Validate(instance); 

     if (!results.IsValid) 
      new ValidationException(result); 

     this.decorated.Save(instance); 
    } 
} 

Autofac을 사용하면 데코레이터를 등록 할 수 있습니다.

+0

자세한 답변을 주셔서 감사합니다 - 유용한 콘텐츠에 대한 upvote 것입니다,하지만 내가 (POST 및 PUT 메서드의 맨 위에) 원래 구현 된 유효성 검사 논리를 모델 클래스로 이동하려는 이유가 있습니다. 특정 클래스 (속성으로 선언 된 규칙과 더 정교한 코드 작성이 필요한 규칙)에 대한 모든 규칙을 한 곳에서 원하기 때문에 IValidatableObject의 편리함을 포기할 준비가되지 않았습니다. – dice

+0

@Steven - 답변 해 주셔서 감사합니다. 그것도 Unity와 함께 작동합니까? 이 시나리오에서 Unity를 설정하는 방법에 대한 힌트가 있습니까? 특히 Unity가 CompositeValidator 의 인스턴스를 어떻게 관련 IEnumerable >으로 생성 할 수 있습니까? – Tohid

+1

@ 토 히드 : 미안 해요. 나는 화합에 경험이있는 사람이 아니다. 여기에 새로운 질문을 게시 해보십시오. 행운을 빕니다 – Steven

관련 문제