Click here to Skip to main content
15,893,508 members
Articles / Desktop Programming / Windows Forms

Bringing AOP to MEF

Rate me:
Please Sign up or sign in to vote.
4.86/5 (36 votes)
11 Jul 2011CPOL14 min read 75.2K   1.3K   87  
An experiment into combining AOP and MEF.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel;

using LinFu.AOP.Interfaces;
using log4net;





namespace AspectableMef
{
    public class LogMethodInvocation : IAroundInvoke
    {


        #region Data
        private static ILog logger;
        private ContextOperations contextOperationsRequired;
        #endregion

        #region Ctor
        public LogMethodInvocation(ILog logger, ContextOperations contextOperationsRequired)
        {
            if (LogMethodInvocation.logger == null)
                LogMethodInvocation.logger = logger;
            this.contextOperationsRequired = contextOperationsRequired;
        }
        #endregion

        #region IAroundInvoke Members

        public void AfterInvoke(IInvocationContext context, object returnValue)
        {
            if(contextOperationsRequired.HasFlag(ContextOperations.OnExiting))
            {
                DoLogging("Exit", context);
            }
        }

        public void BeforeInvoke(IInvocationContext context)
        {
            if (contextOperationsRequired.HasFlag(ContextOperations.OnEntered))
            {
                DoLogging("Enter", context);
            }
        }

        #endregion


        #region Private Methods

        private void DoLogging(string contextOperation, IInvocationContext context)
        {

            // check for the special attribute
            if (!context.TargetMethod.HasAttribute<LogAttribute>())
                return;

            ParameterInfo[] parameters = context.TargetMethod.GetParameters();



            StringBuilder sb = new StringBuilder();
            sb.AppendLine(contextOperation);

            sb.AppendLine(String.Format("{0}.{1}({2}) called with the following parameters ",
                context.GetType().Name,
                context.TargetMethod.Name, GetMethodArgs(parameters)));


            Type[] genArgs = context.TargetMethod.GetGenericArguments();

            sb.AppendLine("\r\nGeneric arguments : ");
            for (int i = 0; i < genArgs.Count(); i++)
            {
                sb.AppendLine(String.Format("[Name:{0}]{1}", genArgs[i].Name,
                    i < genArgs.Count()-1 ? "," : ""));
            }


            sb.AppendLine("\r\nMethod parameters : ");
            for (int i = 0; i < parameters.Count(); i++)
            {
                sb.AppendLine(String.Format("[Name:{0}, Type:{1}, Value:{2}]{3}",
                    parameters[i].Name, GetGenericsForType(parameters[i].ParameterType), context.Arguments[i],
                    i < parameters.Count()-1 ? "," : ""));
            }
            
            logger.Debug(sb.ToString());
        }



        private string GetGenericsForType(Type t)
        {
            string name = "";
            if (!t.GetType().IsGenericType)
            {
                //see if there is a ' char, which there is for
                //generic types
                int idx = t.Name.IndexOfAny(new char[] { '`', '\'' });
                if (idx >= 0)
                {
                    name = t.Name.Substring(0, idx);
                    //get the generic arguments
                    Type[] genTypes = t.GetGenericArguments();
                    //and build the list of types for the result string
                    if (genTypes.Length == 1)
                    {
                        //name+="<" + genTypes[0].Name + ">";
                        name += "<" + GetGenericsForType(genTypes[0]) + ">";
                    }
                    else
                    {
                        name += "<";
                        foreach (Type gt in genTypes)
                        {
                            name += GetGenericsForType(gt) + ", ";
                        }
                        if (name.LastIndexOf(",") > 0)
                        {
                            name = name.Substring(0,
                                name.LastIndexOf(","));
                        }
                        name += ">";
                    }
                }
                else
                {
                    name = t.Name;
                }
                return name;
            }
            else
            {
                return t.Name;
            }
        }



        private string GetMethodArgs(ParameterInfo[] parameters)
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < parameters.Count(); i++)
            {
                sb.AppendFormat("{0} {1}{2}", GetGenericsForType(parameters[i].ParameterType), parameters[i].Name, 
                    i < parameters.Count()-1 ? "," : "");
            }
            return sb.ToString();
        }

        #endregion
    }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)

- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence

Both of these at Sussex University UK.

Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2016
  • Codeproject MVP 2016
  • Microsoft C# MVP 2015
  • Codeproject MVP 2015
  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Comments and Discussions