Caller Information Attributes in .NET 4.5


What ? 
Caller information are set of attributes which are part of . NET Framework 4.5 . These attributes will help the developers in easily capturing the calling method’s name, line number and the file path which are the key attributes for logging/tracing. The attribute names are : 
 a) CallerMemberNameAttribute 
 b) CallerLineNumberAttribute 
 c) CallerFilePathAttribute 

Why ? 
Previously to capture the calling method name, we used to use reflection which causes the performance degradation of the application. Also, it is highly difficult to maintain the line number as well as part of the trace mechanism. With these new attributes, developers can easily capture these information with simple attribute names inside the method. 
The major advantage of these attributes are, these are compile time attributes, meaning the attributes will get replaced with actual attributes once if we compile the source code. No additional load to the application during run time. 

Where ? 
These are majorly useful while Logging/tracing to know the calling method name/file name/line number. 
One another place where we can use the calling method name attribute is during the implementation of INotifyPropertyChanged interface. To notify any property change in wpf, we have to pass the property name to notify the property change. It is mandatory for the developers to ensure that the property name and the notify property name are matching, this dependency can be easily overcome with CallerMemberName attribute.

How ? 
Example usage for logging/tracing. 
Please note that, how to implement logging/tracing is not the intent of the post and so I’m skipping the implementation part of my Logging mechanism
Implementation of Caller information attributes while logging… (Observe the implementaion of attribute before parameter name in the methods)


class LogWriter

    {

        LogIt logger = new LogIt();



        public void LogError(string messageName, Exception ex, [CallerMemberName]string methodName = "", [CallerLineNumber]int lineNumber = -1, [CallerFilePath]string FileName = "")

        {

            logger.LogIt(LogIt.LogType.Error, messageName, ex, methodName, lineNumber, FileName);

        }



        public void LogInformation(string messageName, [CallerMemberName]string methodName = "", [CallerLineNumber]int lineNumber = -1, [CallerFilePath]string FileName = "")

        {

            logger.LogIt(LogIt.LogType.Information, messageName, null, methodName, lineNumber, FileName);

        }

        

    }


Using the Logwriter class in the code… 


void MainWindow_Loaded(object sender, RoutedEventArgs e)

        {

            log.LogInformation("Main window loaded");



            this.DataContext = new Employee();



            log.LogInformation("Main window loading completed");



        }


The above method when compiled and published it would get automatically complied as …


void MainWindow_Loaded(object sender, RoutedEventArgs e)

        {

            log.LogInformation("Main window loaded","MainWindow_Loaded",31,"E:\Projectfolder\subfolder\MainWindow.Xaml.Cs");



            this.DataContext = new Employee();



            log.LogInformation("Main window loading completed","MainWindow_Loaded",31,"E:\Projectfolder\subfolder\MainWindow.Xaml.Cs");



        }

 
You can observe that the optional parameters would get automatically replaced with their actual values. 

In the same way, the implementation can be done for InotifyPropertyChanged interface as shown below. 


private string employeeName="";



        public string EmployeeName

        {

            get { return employeeName; }

            set 

            { 

                employeeName = value;

         

                //****OLD WAY***//

         //OnPropertyChanged("EmployeeName");

 

         //****NEW WAY ****//

                OnPropertyChanged();



            }

        }



        #region INotifyPropertyChanged Implementation



        public event PropertyChangedEventHandler PropertyChanged;



        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")

        {

            

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }





        #endregion


Any Conditions/Rules ? 
There are certain rules that developers need to follow to implement these attributes. First and far most the parameters should be Optional Parameters and the fallback value (optional value) will be used in case if the caller information cannot be processed. 

The Member Name attribute will return “.ctor” if it is called from Constructor and “Finalize” if it is called from Destructor. 

Can be used for any method, attributes. Hope this information helps for a kick start on using these attributes.. 

Regards 
Srikanth 

PS: Please let me know your suggestions via comments to further improve the quality of the posts.

2 thoughts on “Caller Information Attributes in .NET 4.5

  1. Good info. I will use this with log4net rolling file appender, guess it will be helpful when it comes to performance hits.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s