Playing Chicken With Common Sense

Many developers like to stick their data inside the database and load their combo boxes and other application data from it.  There are lots of reasons for doing so such as localizing your data or maybe you can’t write to the local file system for whatever reason.  In my case the local file system is off limits.

So great.  At some point you decide you want some type safety for this data and so you create an Enum for each of your types.  The only problem is that your nice Enums and your database don’t like each other and they get out of sync pretty quickly during development.

The solution I’m going to present is a good starting point.  It will generate enums in c# straight from your database.  I will post the code here so that you can get a head start and hopefully find it useful.

Let’s start by creating a SQL Server database and building a table.  For this demonstration I will create a table for storing ApplicationCodes and specifically Country codes.  There is no reason behind me picking Country Codes other than to show the concept.  You are welcome to pick anything that makes sense for your application.

image

Let’s start visual studio and create two console applications.  The first console app will be responsible for generating the enums and putting the generated code into the second console applications root folder.  I will name them wijix.EnumGenerator and wijix.EnumGenerator.Demo.

image

I’m not going to show you every detail of the code because I have included the source code below.  Just get it and do whatever you like with it but don’t hold me responsible for anything.  Download at your own risk. haha – that’s pretty funny.

wijix.EnumGenerator will now run a sql query and get the data to begin adding it to the CodeDom.  Each TypeName will get it’s own file with every MemberName in the enumerated type.  You can’t assume the data is valid either so it is at this point where a little data scrubbing comes in.  The attached code will format the Enums so that they will compile.

   1: protected string RemoveInvalidCharacters(string enumValueName)
   2: {
   3:     // Remove invalid characters from everywhere and replace them with_
   4:     var level1Correction = Regex.Replace(enumValueName, "[^A-Za-z0-9]+", "_");
   5:     
   6:     // Make sure the name does not begin with a number. if it does add an _ to the beginning
   7:     var number = 0;
   8:     var beginsWithNumber = int.TryParse(level1Correction[0].ToString(), out number);
   9:     
  10:     return beginsWithNumber ? level1Correction.Insert(0, "_") : level1Correction;
  11: }

As you can see the code is very simple.  It will allow certain characters and the bad characters get replaced with an underscore.  It’s simple and effective for generated code.  However, you can modify this to name them however you like.

Everything is formatted and ready to be written to the file system.  It’s just a matter of formatting up the CodeDom with the proper options so that you get a namespace and formatting as desired.

   1: public void WriteEnumToFile(string namespaceToUse, string outputPath)
   2: {
   3:   CodeDomProvider provider = new CSharpCodeProvider();
   4:   var compileUnit = new CodeCompileUnit();
   5:  
   6:   foreach (var enumName in EnumsCollection.Keys)
   7:   {
   8:       var codenamespace = new CodeNamespace(namespaceToUse);
   9:       var codeClass = new CodeTypeDeclaration(enumName)
  10:           {
  11:               IsEnum = true
  12:           };
  13:  
  14:       foreach (var enumNameAndValue in EnumsCollection[enumName])
  15:       {
  16:           var codeProperty = new CodeMemberField
  17:               {
  18:                   Name = enumNameAndValue.Value
  19:               };
  20:  
  21:           codeClass.Members.Add(codeProperty);
  22:       }
  23:  
  24:       codenamespace.Types.Add(codeClass);
  25:       compileUnit.Namespaces.Add(codenamespace);
  26:  
  27:       using (TextWriter textWriter = new StreamWriter(string.Format(@"{0}\{1}.cs", outputPath, enumName)))
  28:       {
  29:           var options = new CodeGeneratorOptions
  30:               {
  31:                   BracingStyle = "C",
  32:                   BlankLinesBetweenMembers = false
  33:               };
  34:           provider.GenerateCodeFromNamespace(codenamespace, textWriter, options);
  35:       }
  36:   }
  37: }

As you can see it is pretty simple to make this work.  This solution only took about an hour to write.  My good friend Adnan Ahmad was very helpful with this and hopefully he will write something on his blog soon.  Also, one last thing I wanted to mention was that the point here was to show how this can be done and not argue the merits of it so I’ll just delete those comments if they show up.

Enjoy!

Download Source

  • 0 Comments
  • E-mail
  • Kick it!
  • Shout it
  • Bookmark and Share

Comments

Control panel

RecentComments

Comment RSS