Click here to Skip to main content
15,881,424 members
Articles / Programming Languages / C#
Tip/Trick

Introducing the KingAOP Framework Part 2 - Exception Handling

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
17 Aug 2013CPOL2 min read 17.2K   110   6   5
In this tip, we will talk about logging and exception handling.

Introduction

In this installment of the series, we will talk about logging and exception handling. Let's say we build a public service and we have to communicate with a bunch of third-party services. It's obvious that we will have situations where we have to handle exceptions. In order to do that, we used to wrap potentially dangerous parts of code into try catch expressions. What if we could have functionality to get all values of properties at the moment when exception occurs? It will be very important information for logging. On the other hand it’s hard, either we will copy paste the same code in every catch expression which is very bad and hard to maintain or create some abstraction for it and stretching cross all code layers where it will be needed. These concerns often cannot be cleanly decomposed from the rest of the system in both the design and implementation, and can result in either scattering (code duplication), tangling (significant dependencies between systems), or both.

Background

This tip assumes that you're familiar with the concept of AOP and PostSharp framework. Also if you're wondering what the entire KingAOP Framework is about, click here.

Using the Code

Ok then, what can we do with AOP? Basically every AOP framework provides us with the ability to intercept exception throwing and handle it like we want. We can continue execution or wrap into another type of exception or just rethrow current exception or even drown exception. Actually our aspect should intercept exception, walk through all properties of instance and write the property's value into log file or elsewhere and finally just rethrow exception. In order to do that, we will inherit from OnMethodBoundaryAspect and override OnException method that will be called when exception occurs.

C#
class ExceptionHandlingAspect : OnMethodBoundaryAspect
{
    // will be called when exception occurs.
    public override void OnException(MethodExecutionArgs args) 
    {
        var str = new StringBuilder();
        str.AppendLine();
        str.Append(args.Exception.Message);
        str.AppendLine();
 
        if (args.Instance != null)
        {
            var instType = args.Instance.GetType();
            str.AppendFormat("Type = {0}; ", instType.Name);
            foreach (var property in instType.GetProperties(BindingFlags.Instance
                                     | BindingFlags.Public | BindingFlags.DeclaredOnly))
            {
                str.AppendFormat("{0} = {1}; ", property.Name,
                                                property.GetValue(args.Instance, null));
            }
        }
        str.AppendLine();
        Console.WriteLine(str.ToString());
 
        args.FlowBehavior = FlowBehavior.RethrowException; // set the flow behavior.
    }
} 

Since for this demo we have to communicate with a bunch of third-party services, let's create our fake public service.

C#
class PublicService 
{
    public string SessionId { get; set; }
    public string ServiceName { get; set; }
    public uint Port { get; set; }
 
    public void Send(TestEntity entity)
    {
        throw new Exception(); // simulate the real exception.
    }
}

Also we have TestEntity class which is our argument of Send method of PublicService class.

C#
class TestEntity
{
    public int Number { get; set; }
    public string Name { get; set; }
} 

In the current moment, we have all things which we need, let's combine them together. Basically we need that our PublicService can be handled by our ExceptionHandlingAspect aspect. In order to work with KingAOP, we have to inherit our PublicService implementation from interface called IDynamicMetaObjectProvider. It's necessary for DLR to invoke our aspect via dynamic. You can think about it as indicator for DLR to do dynamic magic. The IDynamicMetaObjectProvider requires to implement GetMediaObject method. This method should always returns KingAOP's AspectWeaver object which will generate code of aspect. The second step is binding our aspect on public method Send.

C#
class PublicService : IDynamicMetaObjectProvider
{
    public string SessionId { get; set; }
    public string ServiceName { get; set; }
    public uint Port { get; set; }
 
    [ExceptionHandlingAspect] // this aspect will be invoked when exception occurs.
    public void Send(TestEntity entity)
    {
        throw new Exception(); // simulate the real exception.
    }
 
    public DynamicMetaObject GetMetaObject(Expression parameter)
    {
        return new AspectWeaver(parameter, this); // this AspectWeaver will inject AOP mechanics.
    }
} 

Let’s look at the whole demo:

C#
class Program
{
    static void Main()
    {
        var entity = new TestEntity { Name = "Jon", Number = 99 };
 
        // exception handling example
        dynamic publicService = new PublicService
        {
            ServiceName = "TestService",
            Port = 1234,
            SessionId = "123908sdfhjkgdfg"
        };
 
        try
        {
            // here will be thrown exception and we jump into OnException method of
            // ExceptionHandlingAspect instead of jump to catch block.
            publicService.Send(entity);
        }
        catch (Exception ex)
        {
            Console.WriteLine("We catched original exception after 'exception aspect' did his job.");
        }
 
        Console.Read();
    }
}

On console output, we will have:

Image 1

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
Ukraine Ukraine
I work primarily with the .NET technology stack, and specialize in accelerated code production via code generation (static or dynamic), aspect-oriented programming, domain-specific languages.

Comments and Discussions

 
QuestionHow integrate it with WCF service Pin
ARIA 516-Apr-17 0:41
ARIA 516-Apr-17 0:41 
QuestionNot working in an inheritance case Pin
danaea30-Mar-15 7:40
danaea30-Mar-15 7:40 
QuestionWorks with VB.NET?? Pin
LFRDG1-Feb-15 9:42
LFRDG1-Feb-15 9:42 
QuestionLive instances Pin
tolisss11-Sep-14 6:31
tolisss11-Sep-14 6:31 
QuestionThanks Pin
Caner BAKİ28-Apr-14 2:30
Caner BAKİ28-Apr-14 2:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.