2017-10-20 2 views
0

나는 꽤 표준 .net core 2 WebApi 프로젝트를 가지고있다. 액션이 호출 될 때 시작되는 메소드에 속성을 추가하려고합니다.메서드가 호출 될 때 시작되는 메서드에 특성을 추가하는 방법은 무엇입니까?

누군가가 foo 동작에 게시 할 때 아래의 의사 코드에서 POST의 본문을 기록하고 싶습니다. 이를 위해 [LogBody] 특성을 추가합니다. 그러나 실제로 속성에서 메소드를 시작하는 방법을 모르겠습니다.

class SomeController: Controller { 
    [HttpPost] 
    [LogBody] 
    public void foo([FromBody] SomeObj obj) { 
     return View(obj); 
    } 
} 

class LogBodyAttribute: Attribute { 
    void LogIt() { 
     string methodName = getMethodName(); 
     string body = new StreamReader(Request.Body, Encoding.UTF8).ReadToEnd(); 

     SaveData(methodName, body); 
    } 
} 

P. PostSharp로이 작업을 수행 할 수 있다는 것을 알고 있지만 오히려 사용하지 않을 것입니다.

+2

당신은 정말로 속성을 시작할 수 없습니다. 속성은 무언가를 기술하기위한 메타 정보 일뿐입니다. 가장 좋은 추측은 ActionContext를 잡아서 미들웨어 또는 필터를 연결하고이를 기반으로 로깅을 수행하는 것입니다. PostSharp는 속성에 제공된 메타 정보를 기반으로 컴파일시 문자 그대로 메소드에 코드를 추가하여 작동합니다. – Jonesopolis

답변

2

속성은 컴파일 된 코드에 포함되는 정적 메타 데이터를 제공합니다. 이 정보는 런타임에 쿼리하여 논리를 수행하는 데 사용할 수 있습니다. 그러나 속성 자체로는 조치를 트리거 할 수 없습니다.

객체를 감안할 때,이 같은 속성을 얻을 수 있습니다 :

Type type = controller.GetType(); 
var myAttribute = type 
    .GetMethod(methodName) 
    .GetCustomAttributes(true) 
    .OfType<MyAttribute>() 
    .FirstOrDefault(); 

GetCustomAttributes에 부울 인수는 상속 된 속성이 반환해야하는지 여부를 나타냅니다.


어쩌면 당신이 찾고있는 것은 Aspect-oriented programming AOP입니다. 이를 통해 컴파일 후 프로세스에서 메서드 및 속성에 코드를 삽입 할 수 있습니다. 속성을 사용하여 메소드를 포함 시키거나 제외시킬 수 있습니다. C#에서 사용할 수있는 다양한 AOP 제품이 있습니다.


또 다른 접근법은 Decorator pattern을 사용하는 것이다. 데코레이터는 래퍼 클래스와 동일한 API를 제공하는 래퍼 클래스이며 래퍼의 메서드 및 속성에 비헤이비어를 추가 할 수 있습니다. inversion of control (IoC) 컨테이너 또는 Factory method pattern과 함께 사용하면 자동으로 동작을 주입 할 수 있습니다.

관련 문제