Improvement of Generic Enum Parser and .NET Extensions Methods Library for C# and VB.NET

I updated the previous code about Generic Enum Parser. That code is I include into the .NET Extensions Methods Library for C# and VB.NET project in the Codeplex. The code is below,

public static TEnum ParseStringToEnum<TEnum>(this string dataToMatch, bool ignorecase = default(bool))
       where TEnum : struct
{
       return dataToMatch.IsItemInEnum<TEnum>()() ? default(TEnum) : (TEnum)Enum.Parse(typeof(TEnum), dataToMatch, default(bool));
}
 
public static Func<bool> IsItemInEnum<TEnum>(this string dataToCheck)
        where TEnum : struct
{
        return () => { return string.IsNullOrEmpty(dataToCheck) || !Enum.IsDefined(typeof(TEnum), dataToCheck); };
}
If anyone wants to download it please visit here. The code is part of the StringExtensions class.

Codeproject article about Page and Web user control communication.

I just finish writing a tips/tricks article about Asp.Net Page and Web user control communication in Code project. That article is about, if we want to execute a method of Asp.Net page from a event handler of Web user control's control. The article could be found at How to execute Asp.Net Page method from control's event handler of a web user control.

thanks mohammad.

Generic Factory pattern - to switch between Mock and Production environment service

Factory pattern - in my previous article, I explain the factory in detail. One thing came up in my mind about generic factory pattern. This is really handy to have in project. For example if we are working in a environment where service could be tested in Mock or Production environment. And also Mock and Production services using common contracts. So this is a good candidate of Generic Factory. In this article, I will include few sample contracts, production and mock implementation of those contracts, a Service Factory and Test class.
public interface IServiceProxyOne { void ProcessRequest(string data);   }
public interface IServiceProxyTwo { void ProcessRequest(string data);    }
 
public class ServiceProxyOne : IServiceProxyOne
{
  public void ProcessRequest(string data) { /* do something.*/}
}
public class ServiceProxyTwo : IServiceProxyTwo
{
  public void ProcessRequest(string data) { /* do something.*/}
}
 
public class MockServiceProxyOne : IServiceProxyOne
{
  public void ProcessRequest(string data) { /* do something.*/}
}
public class MockServiceProxyTwo : IServiceProxyTwo
{
  public void ProcessRequest(string data) { /* do something.*/}
}
Service Factory implementation code is below,
public static class ServiceFactory
{
     public static IServiceProxyOne CreateServiceProxyOne()
     {
       return GetProxyInstance<IServiceProxyOneMockServiceProxyOneServiceProxyOne>();
     }

     public static IServiceProxyTwo CreateServiceProxyTwo()
     {
       return GetProxyInstance<IServiceProxyTwoMockServiceProxyTwoServiceProxyTwo>();
     }
 
     public static T1 GetProxyInstance<T1, T2, T3>()
            where T2 : T1, new()
            where T3 : T1, new()
     {
       return IsMockEnvironment() ? (T1)new T2() : (T1)new T2();
     }
 
     public static bool IsMockEnvironment() { return !default(bool); }
}
To test the code we can use below,
static void Main(string[] args)
{
    ServiceFactory.CreateServiceProxyOne().ProcessRequest("Service Proxy one test.");
    ServiceFactory.CreateServiceProxyTwo().ProcessRequest("Service Proxy two test.");
} 
thanks mohammad.

 Few C# and Application Design books from Amazon,

Enum Parser - Enum with string as values.

Enum  parser - I already wrote a article about this. The enum I used that article was standard enum i.e.
public enum myEnum{ itemOne =0, itemTwo=1 } etc, but sometimes we need to do something like public enum myEnum{ itemOne ="Zero", itemTwo="One" },unfortunately .Net doesn't support that functionality directly. We need to do some thing different to do the job. One approach I used in this example is to use Attribute for every items in the enum. In the  processing time of this enum we will use reflection, using reflection we loop through attribute values and try to match with given value. Also I implement the related parser for the enum. The code I wrote is below, following code will show the enum and its structure.

public enum EnumWithText{ [TextValue("Clr")] ItemOne = 0,[TextValue("Dlr")]  ItemTwo = 1}
The above enum member has an attribute named TextValueAttribute, the implementation of the above class is as below,
public class TextValueAttribute : Attribute{
    public string TextValue { getprotected set; }
    public TextValueAttribute(string value)
     {TextValue = value;}}
Thats all we need to do. Now we need few methods to get the TextValue from the enum, following Parser class will help us to do the job,
public static class Parser
{
     public static string GetEnumValue(this Enum value)
     {
      Type type = value.GetType();
      FieldInfo fieldInfo = type.GetField(value.ToString());
      TextValueAttribute[] attribs = fieldInfo.GetCustomAttributes(typeof(TextValueAttribute), falseas TextValueAttribute[];
         return attribs.Length > default(int) ? attribs[default(int)].TextValue : null;
     }
     public static T1 ParseEnum<T1, T2>(T2 item)
     {
        return string.IsNullOrEmpty(item.ToString()) ?
        default(T1) :(T1)(Parser.ParseExtension<T1>(typeof(T1), item.ToString(), !default(bool)));
     }

     public static object ParseExtension<T1>(Type type, string stringValue, bool ignoreCase)
      {
        object result = null;string enumStringValue = null;
        if (!type.IsEnum) throw new ArgumentException("Enum type is required.");
         Array.ForEach(type.GetFields(),
                field =>
                {
                    TextValueAttribute[] attrs = field.GetCustomAttributes(typeof(TextValueAttribute), default(bool)) as TextValueAttribute[];
                    if (attrs.Length > default(int))
                        enumStringValue = attrs[default(int)].TextValue;
                    if (string.Compare(enumStringValue, stringValue, ignoreCase) == default(int))
                    {
                        result = Enum.Parse(type, field.Name);
                        return;
                    }
                });
             return result == null ? default(T1) : result;
        }
}
To test above code we could use following test harness code, 
static void Main(string[] args)
{
  string result = EnumWithText.ItemOne.GetEnumValue();
  EnumWithText myEnum1 = Parser.ParseEnum<EnumWithTextstring>("Clr");
  EnumWithText myEnum2 = Parser.ParseEnum<EnumWithTextstring>("Dlr");
  EnumWithText myEnum3 = Parser.ParseEnum<EnumWithTextstring>("None");
}

thanks mohammad.


 Few C# and Application Design books from Amazon,

Microsoft FxCop Sdk, Coding Standard and Custom RuleSet.

Microsoft FxCop Sdk is a library to help write programmers own ruleset i.e. we can write our own code analysis rulesets using FxCop sdk. Now the question is do we need to create our own custom ruleset? The answer depends on the environment of our work. If our work enforce about the coding standard, naming convention strictly then it is handy to have tool set which automatically check the standard etc.

In this article I am going to show how we can create custom ruleset and how to use those in Visual Studio. I use Microsoft Visual Studio 2010 as dev environment, Microsoft FxCop Sdk which comes along with VS 2010 installation. And coding rules, in this case I have two rules (1) All class names should end with 'Test' (2)
All variable names should not start 'm_' or '_'.

I created a solution named CodingStandard, in the solution I created AnalyzerEngine class library, set few dlls as reference. We need FxCopSdk and Microsoft.Cci.dll to reference in the project. Dlls are reference from C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop (this path is based on my VS 2010 installation in Windows 7 box might be different on yours).

Now the coding part, I created a xml file named RuleDefinition.xml with following contents,
<?xml version="1.0" encoding="utf-8" ?>
<Rules FriendlyName="Naming Standard Rules">
  <Rule
    TypeName="TypeNameAnalyzer"
    Category="AnalyzerEngine.CodingStandard"
    CheckId="AE0001">
    <Name>All class names should end with 'Test'</Name>
    <Description>TypeNameAnalyzer rule will check whether the class name ends with Test.</Description>
    <Url></Url>
    <Resolution Name="ClassNameResolution">The name of type {0} does not end with the suffix 'Test'. Add the suffix to the type name.</Resolution>
    <MessageLevel Certainty="95">Warning</MessageLevel>
    <FixCategories>Breaking</FixCategories>
    <Email />
    <Owner />
  </Rule>
 
  <Rule
    TypeName="VariableNameAnalyzer"
    Category="AnalyzerEngine.CodingStandard"
    CheckId="AE0002">
    <Name>All variable names should not start 'm_' or '_'</Name>
    <Description>VariableNameAnalyzer rule will check whether the variable name starts with m_ or _.</Description>
    <Url></Url>
    <Resolution Name="PrivateMemberNameResolution">The name of type {0} start with m_ or _</Resolution>
    <MessageLevel Certainty="95">Warning</MessageLevel>
    <FixCategories>Breaking</FixCategories>
    <Email />
    <Owner />
  </Rule>
</Rules>

base class named AnalyzerBase.cs with the following contents,

namespace AnalyzerEngine
{
    using Microsoft.FxCop.Sdk;
    public abstract class AnalyzerBase : BaseIntrospectionRule    {
        protected AnalyzerBase(string rule)
            : base(rule, "AnalyzerEngine.RuleDefinition.xml"typeof(AnalyzerBase).Assembly)
        { }
    }
}
in the above code BaseIntrospectionRule is from FxCop.Sdk and xml file name will be Namespace + "." + XML file name so in the case namespace is AnalyzerEngine and xml file name RuleDefinition.xml => AnalyzerEngine.RuleDefinition.xml. Also xml file has to be Embedded Resource of this assembly, so right click on this xml file select Properties -> then set the Build Action as Embedded Resource.

Two other rule classes TypeNameAnalyzer.cs and VariableNameAnalyzer.cs

TypeNameAnalyzer.cs
namespace AnalyzerEngine
{
    using System;
    using Microsoft.FxCop.Sdk;
    public class TypeNameAnalyzer : AnalyzerBase    {
        private readonly string classNameEndsWith = "Test";
        private readonly string resolutionName = "ClassNameResolution";
        public TypeNameAnalyzer()
            : base("TypeNameAnalyzer")
        { }
        public override ProblemCollection Check(TypeNode type)
        {
            if (!type.Name.Name.EndsWith(classNameEndsWith, StringComparison.Ordinal))
            {
                var classNameResolutionDetails = GetNamedResolution(resolutionName, type.Name.Name);
                var classNameProblem = new Problem(classNameResolutionDetails, type);
                Problems.Add(classNameProblem);
            }
            return Problems;
        }
    }
}
VariableNameAnalyzer.cs
namespace AnalyzerEngine
{
    using Microsoft.FxCop.Sdk;
    public class VariableNameAnalyzer : AnalyzerBase    {
        private readonly string vairableNameStartsWith_m = "m_";
        private readonly string vairableNameStartsWith_underscore = "_";
        private readonly string resolutionName = "PrivateMemberNameResolution";
        public VariableNameAnalyzer()
            : base("VariableNameAnalyzer")
        { }
        public override ProblemCollection Check(Member member)
        {
            Field variable = member as Field;
            if (variable == nullreturn Problems;
            if (variable.Name.Name.StartsWith(vairableNameStartsWith_m, System.StringComparison.Ordinal) ||
                variable.Name.Name.StartsWith(vairableNameStartsWith_underscore, System.StringComparison.Ordinal))
            {
                var resolutionDetails = GetNamedResolution(resolutionName, variable.Name.Name);
                var problem = new Problem(resolutionDetails, variable);
                Problems.Add(problem);
            }
            return Problems;
        }
    }
}

the Last bit is to create a ruleset file, in this case I created a ruleset named CodingStandardRules.ruleset with following contents
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Coding Standard Rules" Description=" " ToolsVersion="10.0">
  <RuleHintPaths>
    <Path>C:\Common\CodingStandardRules</Path>
  </RuleHintPaths>
  <Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
    <Rule Id="AE0001" Action="Error" />
    <Rule Id="AE0002" Action="Error" />
  </Rules>
</RuleSet>

Now build this library. If we see the ruleset file from above then we can see a tag named <Path> this tag refers to the place in where we going to place our newly created assembly and the ruleset file so from where everyone(programmer in the team) can use to run the code analysis. After compiling the project we will get assembly AnalyzerEngine.dll, copy this dll along with CodingStandardRules.ruleset into the C:\Common\CodingStandardRules\ folder on my dev box. In the work environment should the folder should be somewhere in the network so then everyone can use the same information.

To test the rules I am going the create another project named AnalyzerEngine-TestHarness in the CodingStandard solution. The project has only simple Program.cs file with following contents,
namespace AnalyzerEngine_TestHarness
{
    class Program    {
        static void Main(string[] args)
        {
        }
    }
    public class CodingStandardClassname    {
        private string name = "I am string";
        private string _name = "I am string";
    }
}

Now we need to set our ruleset with this project, So right click on the project -> select Propertites -> from the new window click on the Code Analysisi tab from the left.From this window under Run this rule set  combo bex select the <Browse> option then it will pop up file dialog from there select the CodingStandardRules.ruleset file which is in this case in C:\Common\CodingStandardRules here, see the image below


Fig: Set options in Code analysis window

So all done build the  AnalyzerEngine-TestHarness project and we will get following errors,


Fig: Code analysis output.

I found following resources are really helpful for extra information in regards to FxCop,


I will try to upload the source code sometimes later. Thanks mohammad.

 Few C# and Application Design books from Amazon,