Friday, January 18, 2008

Access Private Fields And Invoke Private Methods In .NET

using System;
using System.Reflection;

class Test
{
private int _number;
private int Number
{
get { return _number; }
set { _number = value; }
}

private int PrivateAdd(int a, int b)
{
return a + b;
}

private static int StaticAdd(int a, int b)
{
return a + b;
}

static void Main()
{
//Instance method
Test test = new Test();
MethodInfo privateMethod = test.GetType().GetMethod("PrivateAdd",
BindingFlags.NonPublic | BindingFlags.Instance);
object[] parameters = new object[] { 1, 2 };
int result = (int)privateMethod.Invoke(test, parameters);

//Static method
MethodInfo staticMethod = typeof(Test).GetMethod("StaticAdd",
BindingFlags.NonPublic | BindingFlags.Static);
result = (int)staticMethod.Invoke(null, parameters);

//Private field
FieldInfo privateField = test.GetType().GetField("_number",
BindingFlags.NonPublic | BindingFlags.Instance);
privateField.SetValue(test, 123);
result = (int)privateField.GetValue(test);

//Private property
PropertyInfo privateProperty = test.GetType().GetProperty("Number",
BindingFlags.NonPublic | BindingFlags.Instance);
privateProperty.SetValue(test, 456, null);
result = (int)privateProperty.GetValue(test, null);

Console.WriteLine("Done");
Console.Read();
}
}

Saturday, January 12, 2008

Configure Log4Net To Log Different Files For Different Projects

Log4Net is a free logging helper running in .NET environment (ported from Log4j). By configuration setting you can log message to files, event log, console window, etc. The common usage is logging to one file, but you can also separate the log files for different projects if you want. Following configuration is an example to separate web UI project logs and backend class library logs:
  <log4net>
<appender name="RollingFileAppenderBackend" type="log4net.Appender.RollingFileAppender">
<file value="C:\inetpub\logs\Backend.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="100" />
<maximumFileSize value="1000KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p: %m%n" />
</layout>
</appender>
<appender name="RollingFileAppenderWebUI" type="log4net.Appender.RollingFileAppender">
<file value="C:\inetpub\logs\WebUI.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="100" />
<maximumFileSize value="1000KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p: %m%n" />
</layout>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<param name="Header" value="[Header]\r\n" />
<param name="Footer" value="[Footer]\r\n" />
<param name="ConversionPattern" value="%d [%t] %-5p: %m%n" />
</layout>
</appender>
<logger name="Backendlogger">
<level value="DEBUG" />
<appender-ref ref="RollingFileAppenderBackend" />
<appender-ref ref="EventLogAppender" />
<appender-ref ref="ConsoleAppender" />
</logger>
<logger name="UILogger">
<level value="DEBUG" />
<appender-ref ref="RollingFileAppenderWebUI" />
<appender-ref ref="ConsoleAppender" />
</logger>
</log4net>