Mar 6, 2009

Dispose and Finalize methods and .NET Memory optimizations

I have jotted down a few points on implementing the IDisposable and Finalize patterns in .NET.

Please find it here : Dispose and Finalize methods

I also jotted down some .net Memory Optimization tips: Please find them here : Some Tips on .NET Memory optimizations

Mar 3, 2009

Creating dynamically generated logfiles with log4net

If you need to generate logfile names dynmically when using log4net then we can do this using the log4net Properties.

To learn more on this please visit : creating dynamic logfile names with log4net

Tips on using log4net RollingFileAppender

I have compiled a list of useful properties that you can set on the RollingFileAppender in the log4net XML config file which can determine the order in which log file backups will be generated, whether they will rollover based on dates or size or both.

For more information please check this link out : Tips on using log4net RollingFileAppender

Jan 28, 2009

ConfigSectionHandler for Hierarchical configs

Here is a quick way to create a ConfigSection Handler for reading Hierarchical configs. For e.g. suppose you need to read a config file which has the following structure:

MySpace

23
Rohit
Gupta


For this you would create the 2 classes, one for the Parent Config and another for the chold config like this:

[XmlRoot("MainConfig")]
public class MainConfig
{
private static readonly MainConfig instance =
(MainConfig)ConfigurationManager.GetSection("MainConfig");
public static MainConfig GetInstance()
{
if (instance == null)
throw new ConfigurationErrorsException(
"Unable to locate or deserialize the 'MainConfig' section.");

return instance;
}

public string Company { get; set; }

public SubConfig FriendsConfig { get; set; }
}

[XmlRoot("SubConfig")]
public class SubConfig
{
public int ID { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
}

Then you would create a configsectionHandler class which reads the config from the .config file:


public class MainConfigSectionHandler : IConfigurationSectionHandler
{
#region IConfigurationSectionHandler Members

public object Create(object parent, object configContext, System.Xml.XmlNode section)
{
MainConfig typedConfig = GetConfig(section);

if (typedConfig != null)
{
#region Get Sub Configs
foreach (XmlNode node in section.ChildNodes)
{
switch (node.Name)
{
case "SubConfig":
SubConfig friendsConfig = GetConfig(node);
typedConfig.FriendsConfig = friendsConfig;
break;
default:
break;
}
}
#endregion
}


return typedConfig;
}

public T GetConfig(System.Xml.XmlNode section) where T : class
{
T sourcedObject = default(T);
Type t = typeof(T);
XmlSerializer ser = new XmlSerializer(typeof(T));
sourcedObject = ser.Deserialize(new XmlNodeReader(section)) as T;
return sourcedObject;
}

#endregion

}

After this you would add a entry in the app.config for this configsection Handler as the following:





Finally to read this config, you would write the following:

MainConfig config = MainConfig.GetInstance(); Console.WriteLine(config.Company);
Console.WriteLine(config.FriendsConfig.ID);
Console.WriteLine(config.FriendsConfig.LastName);
Console.WriteLine(config.FriendsConfig.Name);

Jan 7, 2009

Lucene: Multifield searches

We can run multifield searches in Lucene using either the BooleanQuery API or using the MultiFieldQueryParser for parsing the query text. For e.g. If a index has 2 fields FirstName and LastName and if you need to search for "John" in the FirstName field and "Travis" in the LastName field one can use a Boolean Query as such:


BooleanQuery bq = new BooleanQuery();
Query qf = new TermQuery(new Lucene.Net.Index.Term("FirstName", "John"));
Query ql = new TermQuery(new Lucene.Net.Index.Term("LastName", "Travis"));
bq.Add(qf, BooleanClause.Occur.MUST);
bq.Add(ql, BooleanClause.Occur.MUST);
IndexSearcher srchr = new IndexSearcher(@"C:\indexDir");
srchr.Search(bq);

Now if we need to search a single term across either of the FirstName and LastName fields then we can use the MultiFieldQueryParser as follows:

Query query = MultiFieldQueryParser.parse("commonName",
new String[] { "FirstName", "LastName" },
new SimpleAnalyzer());
srchr.Search(query);

Now if you need to search the term that must exist in both the fields then we use the following:

Query query = MultiFieldQueryParser.Parse("commonName",
new String[] { "FirstName", "LastName" },
new BooleanClause.Occur[] { BooleanClause.Occur.MUST,BooleanClause.Occur.MUST}
, new SimpleAnalyzer());
srchr.Search(query);

Finally if you don’t want a term to occur in one of the Fields (say FirstName) then use:

Query query = MultiFieldQueryParser.Parse("commonName",
new String[] { "FirstName", "LastName" },
new BooleanClause.Occur[] { BooleanClause.Occur.MUST_NOT,BooleanClause.Occur.MUST},
new SimpleAnalyzer());
srchr.Search(query);

so if you need to search a single term across multiple fields then use MultiFieldQueryParser, if you need to search different terms in different fields then use the BooleanQuery as shown first

Dec 1, 2008

Dynamically creating types using reflection and setting properties using Reflection.Emit.

I came across a requirement where we needed to create types dynamically based on XML Configuration files, so that in the furture new types are required we dont need to update the application again by creating a new class.
The additional requirement was to populate the property names of the class based on the Cml configuration and its values using the Querystring values from the HttpWebRequest.
I earlier thought about using Dynamic methods from .NET Framework 2.0, but that did not fit my purpose since I didn't need to execute methods from the dynamic type that was created.

So here is the code:
I created three helper methods
1. Generates the AssemblyBuilder and Module Builder objects
2. Generates the TypeBuilder object.. which will be used for generating an instance of the dynamic type using Activator.CreateInstance
3. Create properties using Relection.Emit
   1: public class DynamicType
   2: {
   3:  
   4:     public static AssemblyBuilder asmBuilder = null;
   5:     public static ModuleBuilder modBuilder = null;
   6:     public static void GenerateAssemblyAndModule()
   7:     {
   8:         if (asmBuilder == null)
   9:         {
  10:             AssemblyName assemblyName = new AssemblyName();
  11:             assemblyName.Name = "DWBeacons";
  12:             AppDomain thisDomain = Thread.GetDomain();
  13:             asmBuilder = thisDomain.DefineDynamicAssembly(
  14:                          assemblyName, AssemblyBuilderAccess.Run);
  15:             modBuilder = asmBuilder.DefineDynamicModule(
  16:                          asmBuilder.GetName().Name, false);
  17:         }
  18:     }
  19:  
  20:     public static TypeBuilder CreateType(ModuleBuilder modBuilder, string typeName)
  21:     {
  22:         TypeBuilder typeBuilder = modBuilder.DefineType(typeName,
  23:                     TypeAttributes.Public |
  24:                     TypeAttributes.Class |
  25:                     TypeAttributes.AutoClass |
  26:                     TypeAttributes.AnsiClass |
  27:                     TypeAttributes.BeforeFieldInit |
  28:                     TypeAttributes.AutoLayout,
  29:                     typeof(object));
  30:         return typeBuilder;
  31:     }
  32:  
  33:  
  34:     public static void CreateProperty(TypeBuilder t, string name, Type typ)
  35:     {
  36:         string field = "_" + name.ToLower();
  37:         FieldBuilder fieldBldr = t.DefineField(field, typ, FieldAttributes.Private);
  38:         PropertyBuilder propBldr = t.DefineProperty(name, PropertyAttributes.HasDefault, typ, null);
  39:         MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
  40:  
  41:         MethodBuilder getPropBldr = t.DefineMethod("get_" + name, getSetAttr, typ, Type.EmptyTypes);
  42:  
  43:         ILGenerator getIL = getPropBldr.GetILGenerator();
  44:         getIL.Emit(OpCodes.Ldarg_0);
  45:         getIL.Emit(OpCodes.Ldfld, fieldBldr);
  46:         getIL.Emit(OpCodes.Ret);
  47:  
  48:         MethodBuilder setPropBldr = t.DefineMethod("set_" + name, getSetAttr, null, new Type[] { typ });
  49:  
  50:         ILGenerator setIL = setPropBldr.GetILGenerator();
  51:  
  52:         setIL.Emit(OpCodes.Ldarg_0);
  53:         setIL.Emit(OpCodes.Ldarg_1);
  54:         setIL.Emit(OpCodes.Stfld, fieldBldr);
  55:         setIL.Emit(OpCodes.Ret);
  56:  
  57:         propBldr.SetGetMethod(getPropBldr);
  58:         propBldr.SetSetMethod(setPropBldr);
  59:  
  60:     }
  61:  
  62: }



Then to use these helper methods from the Main program I used the following:

   1: if (DynamicType.asmBuilder == null)
   2:     DynamicType.GenerateAssemblyAndModule();
   3: finalType = DynamicType.modBuilder.GetType("Beacon11");
   4:  
   5: TypeBuilder tb = DynamicType.CreateType(DynamicType.modBuilder, typeName);
   6:  
   7: foreach (XElement e in beaconNode.Descendants())
   8: {
   9:     string pname = e.Attribute("qs").Value;
  10:     string ptype = e.Attribute("type").Value;
  11:     DynamicType.CreateProperty(tb, pname, Type.GetType(ptype));
  12: }
  13: finalType = tb.CreateType();
  14:  
  15: Object obj = Activator.CreateInstance(finalType);
  16: // this sets the properties of the just instantiated class
  17: finalType.InvokeMember("bv", BindingFlags.SetProperty, null, data, new object[] { 1.0 });
  18: finalType.InvokeMember("tp", BindingFlags.SetProperty, null, data, new object[] { 2.0 });
  19: //this sets the properties of the type by using values from the querystring
  20: foreach (XElement e in beaconNode.Descendants())
  21: {
  22:     string pname = e.Attribute("qs").Value;
  23:     object value = context.Request.QueryString[pname];
  24:     finalType.InvokeMember(pname, BindingFlags.SetProperty, null, data, new object[] { value });
  25: }


For more information visit : msdn - PropertyBuilder

Nov 18, 2008

Schedule a task using C# code

I needed to schedule a task to run every day at 9:00 p.m. in the night. I had an addition al requirement that the task be scheduled only if the FileSystemwatcher alerts us of new files being available for processing.

Thus the files could be recieved anytime during the day, but despite that the task should be schduled to run exactly at 9:00 p.m. in the night.

So I used the following code to schedule a task(using System.Threading.Timer and TimeSpan classes)

DateTime d = DateTime.Now;

timer = new Timer(new TimerCallback(Update), null,
TimeSpan.FromMinutes(21 * 60 - (d.Hour * 60 + d.Minute)),
TimeSpan.FromMilliseconds(-1));


Note I used TimeSpan.FromMillisecnods(-1) to disable periodic signalling

Nov 13, 2008

Compare 2 SQL queries for equality

DECLARE @check1 bigint
DECLARE @check2 bigint

Select @check1 = CHECKSUM_AGG(CHECKSUM(*))
FROM
(
SELECT *
FROM dbo.Orders (nolock)
)
AS Source

Select @check2 = CHECKSUM_AGG(CHECKSUM(*))
FROM
(
SELECT *
FROM dbo.Orders (nolock)
WHERE IsSuccessful = 1
)
As Comparison

IF @check1 = @check2
PRINT 'Queries are Equal'
ELSE
PRINT 'Queries are NOT Equal'


Note:
If order of rows is different it will not effect the result
It does not do execution plan comparisons, simply checks if the rows returned by the two queries are the same or not

More info