Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Dynamic Casting with .NET

DZone's Guide to

Dynamic Casting with .NET

·
Free Resource

I recently was working on a project where I needed to store settings or various data types into a database table. Since most of the settings were singular I ended up with a table that had two columns which were titled name and value. The name and value field of the Setting table are both defined as varchars ( or strings). By defining the value field as a string, I can serialize any object to the table by using the ToString() method.

Over time my application could grow to have dozens of settings of varying data types. So I needed a mechanism to load the settings from the table and assign them to an object. While loading each setting, I need to dynamically determine the data type of each field and dynamically cast it to the correct type.

Since my project is written in MVC I developed a Model class which represents all of the settings that I need to reference. Here is the definition:

namespace WeBlog.Models {    
public class SettingsModel {
//general settings
[Required]
public string SiteName { get; set; }
public string SiteDescription { get; set; }
[Required]
public int PostsPerPage { get; set; }
public string Theme { get; set; }
public Boolean AreCommentsEnabled { get; set; }
public bool SendCommentEmail { get; set; }
public string DateFormat { get; set; }

//email related settings
public string EmailAddress { get; set; }
public string SMTPHost { get; set; }
public int SMTPPort { get; set; }
public string SMTPEncryption { get; set; }
public bool SMTPAuthentication { get; set; }
public string SMTPUsername { get; set; }
public string SMTPPassword { get; set; }
public string SubjectPrefix { get; set; }
}
}

And here is the settings table. As you can see from the table definition, each value is stored as a string:

Settings Table

Here are some sample values. As you can see we have booleans, integers and string stored in the table:

Name Value
AreCommentsEnabled True
DateFormat MM/dd/yyyy HH:mm
EmailAddress admin@site.com
PostsPerPage 10
SendCommentEmail True
SiteDescription The ultimate blogging engine
SiteName WeBlog
SMTPAuthentication False
SMTPEncryption None
SMTPHost  
SMTPPassword  
SMTPPort  
SMTPUsername  
SubjectPrefix  
Theme Emporium

 

So now the question becomes, how can I load the data from the data and ensure that it is casted to the proper type? Well, since I have a 1 to 1 mapping between the properties in my Model and the fields in my table I can loop over all the properties in my SettingsModel class, obtain the property name, locate the matching row in the Settings table and cast it to the right type by getting the type of each property using reflection.

public Models.SettingsModel FindSettings() {
Models.SettingsModel settings = new SettingsModel();
Type type = settings.GetType();
PropertyInfo[] properties = type.GetProperties();

using (WeBlogEntities db = new WeBlogEntities()) {
var data = from x in db.Settings select x;
foreach (Setting s in data) {
if (String.IsNullOrEmpty(s.Value)) continue;
PropertyInfo pInfo = type.GetProperty(s.Name);
pInfo.SetValue(settings, Convert.ChangeType( s.Value, pInfo.PropertyType), null);
}
}

return settings;
}

Admittedly, storing settings in a generic table is not always the best solution. However, if you need a flexible solution that allows you to easily add new settings without reworking a lot of code then this may be ideal for you. In any case, dynamic casting via reflection really is an ideal solution for this particular problem.

 

Topics:

Published at DZone with permission of Michael Ceranski, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}