How can i use simple aspect oriented concept to ha

2019-04-03 00:18发布

问题:

i want to use AOP to handle my error exception in Console application. ( it is not MVC i used attribute vase programing to handle errors in mvc but this is console app) My code below: ( if error occurs ,it should throw an error yo my attribute side code )

 [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class HandleError : Attribute
{
     public HandleError(string description)
    {
        try
        {
            this.Description = description;
        }
        catch (Exception)
        {

            throw;
        }

    }
    public string Description { get; set; }


}

this will call from my method :

   [HandleError("Error occurs here")]
    public static void MyMethod(string data)
    {
        throw new Exception();

Actually; i want to use AOP to handle exceptions inside my method. i have to call attributes if it error occurs. But How? ( please don't offer postsharp, it needs money. but i am open for opensource also)By the way; why it is not easy ,i don't understand.

回答1:

Basically, what PostSharp does is to weave code into your assembly at compile time that is run before and after the methods that are marked with the attributes. This is very good from a performance point of view because there is no use of code that is created dynamically at runtime.

Some other AOP frameworks (or IoC containers) offer the option to generate dynamic proxies that contain code that intercepts the calls to the methods at runtime.

Either you use one of those frameworks (look for IoC and interception) or you implement a comparable functionality by yourself. Basically what you have to do is to move the code you want to intercept into a class and mark the methods as virtual. At runtime, you decorate the instance of the class with a dynamically created class that inherits from your class and overrides the methods so that the additional code is run before and after the call to the method.

However, there might be a simpler approach that fits the needs of a console application. Instead of marking the methods with an attribute, you could also create some helper functions that contain the code that you want to run before and after the method:

void Main()
{
    int value = GetValue(123);
    DoSomething(value);
}

void DoSomething(int myParam)
{
    RunAndLogError(() => {
        // Place code here
        Console.WriteLine(myParam);
        });
}

int GetValue(int myParam)
{
    return RunAndLogError(() => {
        // Place code here
        return myParam * 2;});
}

void RunAndLogError(Action act)
{
    try
    {
        act();
    }
    catch(Exception ex)
    {
        // Log error
        throw;
    }
}

T RunAndLogError<T>(Func<T> fct)
{
    try
    {
        return fct();
    }
    catch(Exception ex)
    {
        // Log error
        throw;
    }
}

As you can see, there are two overloads of RunAndLogError, one for void methods, the other one for methods that return a value.

Another option is to use a global exception handler for this purpose; see this answer for details: .NET Global exception handler in console application