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 comments
Good info. I will use this with log4net rolling file appender, guess it will be helpful when it comes to performance hits.
ReplyYup, You are right.. With log4net you can do better with this approach...
ReplyPost a Comment
Hey, dont forget to leave your name if your giving comment as anonymous user :)