문제

는 방법이 있 C#또는.순서는 일반적인 특성을 만들 방법에는 이벤트가 트리거 될 때 메소드가 호출될?이상적으로,내가 할 수 있 사용자 지정 작업을 실행하기 전과 후의 호출 방법입니다.

나는 뭔가 의미 다음과 같다:

[TriggersMyCustomAction()]
public void DoSomeStuff()
{
}

나는 완전히 우둔 그것을 어떻게 또는 그것 가능한 경우에는 모든하지만, 시스템입니다.Diagnostic.ConditionalAttribute 수도 비슷한 일이다.나는 확실하지 않지만.

편집:말 것도 그 때문에 상황의 특정한 경우,성능상 문제가 되지 않.

도움이 되었습니까?

해결책

내가 이것을하는 방법을 아는 유일한 방법은 포스트 쇼트. 그것은 당신의 IL을 사후 처리하고 당신이 요청한 것과 같은 일을 할 수 있습니다.

다른 팁

이 개념에서 사용되는 MVC 웹 응용 프로그램입니다.

.NET Framework4.x 제공하는 몇 가지 특성이 있는 액션을 트리거,예를 들어: ExceptionFilterAttribute (예외 처리), AuthorizeAttribute (취급 authorization).모두에서 정의 System.Web.Http.Filters.

당신은 예를 들어 정의한 당신의 자신의 권한 부여 특성이 다음과 같다:

public class myAuthorizationAttribute : AuthorizeAttribute
{
    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        // do any stuff here
        // it will be invoked when the decorated method is called
        if (CheckAuthorization(actionContext)) 
           return true; // authorized
        else
           return false; // not authorized
    }

}

그런 다음 컨트롤러 클래스를 장식하는 방법을 사용하여 당신의 권한 부여 다음과 같다:

[myAuthorization]
public HttpResponseMessage Post(string id)
{
    // ... your code goes here
    response = new HttpResponseMessage(HttpStatusCode.OK); // return OK status
    return response;
}

할 때마다 Post 메소드가 호출될 것,전화 IsAuthorized 메서드 myAuthorization 특성 코드부 Post 메소드가 실행됩니다.

당신이 돌아 falseIsAuthorized 방법은,당신은 신호는 권한이 부여되지 않고 실행하는 방법 Post 이 중단됩니다.


을 이해하는 방법을 이 작품들에 대해 자세히 살펴보도록 하자는 다른 예를 들어:이 ExceptionFilter, 할 수 있는 예외를 필터링을 사용하여 특성,사용법은 비슷한 위와 같이 대 AuthorizeAttribute (당신이 찾을 수 있습니다에 대한 자세한 설명에 대해 그것의 사용 ).

그것을 사용하려면,파생 DivideByZeroExceptionFilter 에서 클래스 ExceptionFilterAttribute 으로 표시 , 과 재정의 방법 OnException:

public class DivideByZeroExceptionFilter : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Exception is DivideByZeroException)
        {
            actionExecutedContext.Response = new HttpResponseMessage() { 
                Content = new StringContent("An error occured within the application.",
                                System.Text.Encoding.UTF8, "text/plain"), 
                StatusCode = System.Net.HttpStatusCode.InternalServerError
                };
        }
    }
}

다음을 사용하여 다음과 같은 데모를 트리거하는 코드 그것:

[DivideByZeroExceptionFilter]
public void Delete(int id)
{
    // causes the DivideByZeroExceptionFilter attribute to be triggered:
    throw new DivideByZeroException(); 
}

지금 우리가 알고있는 어떻게 사용되는,우리는 주로 관심이 있에서 구현됩니다.다음 코드에서입니다.NET Framework.그것을 사용하여 인터페이스 IExceptionFilter 내부적으로는 계약:

namespace System.Web.Http.Filters
{
    public interface IExceptionFilter : IFilter
    {
        // Executes an asynchronous exception filter.
        // Returns: An asynchronous exception filter.
        Task ExecuteExceptionFilterAsync(
                    HttpActionExecutedContext actionExecutedContext, 
                    CancellationToken cancellationToken);
    }
}

ExceptionFilterAttribute 자체의 정의는 다음과 같습니다.

namespace System.Web.Http.Filters
{
    // Represents the attributes for the exception filter.
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, 
            Inherited = true, AllowMultiple = true)]
    public abstract class ExceptionFilterAttribute : FilterAttribute, 
            IExceptionFilter, IFilter
    {
        // Raises the exception event.
        // actionExecutedContext: The context for the action.</param>
        public virtual void OnException(
            HttpActionExecutedContext actionExecutedContext)
        {
        }
        // Asynchronously executes the exception filter.
        // Returns: The result of the execution.
        Task IExceptionFilter.ExecuteExceptionFilterAsync(
            HttpActionExecutedContext actionExecutedContext, 
            CancellationToken cancellationToken)
        {
            if (actionExecutedContext == null)
            {
                throw Error.ArgumentNull("actionExecutedContext");
            }
            this.OnException(actionExecutedContext);
            return TaskHelpers.Completed();
        }
    }
}

ExecuteExceptionFilterAsync, 방법 OnException 라고 합니다.당신이 있기 때문에 재정의 그림과 같이 이전에 오류 처리할 수 있습에 의해 자신의 코드입니다.


거기에는 또한 상업적인 제품으로 사용할 수 있에서 언급 OwenP 의 답변, PostSharp, 할 수 있는 그렇게 쉽습니다. 예입니다 어떻게 당신이 할 수 있는 PostSharp.참고가 있는 익스프레스 버전 사용할 수 있는 무료로 사용할 수 있습도에 대한 상업 프로젝트입니다.

PostSharp 예 (링크를 참조 위에 설명):

public class CustomerService
{
    [RetryOnException(MaxRetries = 5)]
    public void Save(Customer customer)
    {
        // Database or web-service call.
    }
}

여기에 속성을 지정하는 Save 방법은 최대 5 배까지는 경우는 예외가 발생합니다.다음 코드를 정의 이용 속성:

[PSerializable]
public class RetryOnExceptionAttribute : MethodInterceptionAspect
{
    public RetryOnExceptionAttribute()
    {
        this.MaxRetries = 3;
    }

    public int MaxRetries { get; set; }

    public override void OnInvoke(MethodInterceptionArgs args)
    {
        int retriesCounter = 0;

        while (true)
        {
            try
            {
                args.Proceed();
                return;
            }
            catch (Exception e)
            {
                retriesCounter++;
                if (retriesCounter > this.MaxRetries) throw;

                Console.WriteLine(
                    "Exception during attempt {0} of calling method {1}.{2}: {3}",
                    retriesCounter, args.Method.DeclaringType, args.Method.Name, e.Message);
            }
        }
    }
}

일종의 측면 지향 프레임 워크가 필요합니다. PostSharp는 Will과 같이 할 것입니다 윈저.

기본적으로 그들은 당신의 객체를 서브 클래스 하고이 방법을 무시합니다 ...

그런 다음 :

//proxy
public override void DoSomeStuff()
{
     if(MethodHasTriggerAttribute)
        Trigger();

     _innerClass.DoSomeStuff();
}

물론이 모든 것이 당신에게 숨겨져 있습니다. Windsor에게 유형을 물어 보는 것만 큼, 그것은 당신을 위해 프록시를 할 것입니다. 이 속성은 윈저에서 생각하는 (맞춤형) 시설이됩니다.

ContextBoundObject 및 iMessagesInk를 사용할 수 있습니다. 보다 http://msdn.microsoft.com/nb-no/magazine/cc301356(en-us).aspx

이 접근법은 직접 방법 호출과 비교하여 심각한 성능 영향을 미칩니다.

나는 속성만으로 그것을 할 수있는 방법이 없다고 생각하지만 프록시 클래스 그리고 반성 당신은 당신이 방법에 귀속 된 클래스의 인스턴스를 가로 채는 것을 알고있는 수업을 가질 수 있습니다.

그런 다음 프록시 클래스는 귀속 된 메소드가 호출 될 때마다 이벤트를 트리거 할 수 있습니다.

속성은 정보를 제공하고 메타 데이터입니다. 나는 이것을 해제하는 방법을 모른다. 누군가가 할 수도있다.

.NET의 부분 방법을 볼 수있어 가벼운 이벤트 처리를 수행 할 수 있습니다. 후크를 제공하고 다른 사람이 구현을 처리하도록합니다. 메소드가 구현되지 않으면 컴파일러가 무시합니다.

http://msdn.microsoft.com/en-us/library/wa80x488.aspx

가난한 사람의 해결책을 살펴볼 수 있습니다 : 데코레이터 패턴을 참조하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top