Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Data Validation Using .NET and External Metadata

Data validation is a task that we perform every day when writing code. Applying the techniques described here can make your systems more robust and eliminate the constant rebuilding of applications every time a business rule changes.

sing .NET reflection and external metadata makes it easy to add data validation to your objects. Nearly every application that collects data, whether from a Windows- or Web-based form or from a file, needs to validate that the data is in the correct format.

Each programmer has developed his or her own method of validating input data in varying degrees of complexity, but generally, this has resulted in coding the data validation rules into the procedural or object code. This has meant re-compiling and re-distributing your application each time the validation rules changed.

Some have attempted to build a better mousetrap over the years, and some of those efforts have resulted in a somewhat improved ability to separate the validation from the rest of the processing so that the rules could change without having to rebuild the entire application. Storing the validation rules externally, such as in a SQL Server database, is one way to accomplish such a task. However, that only solves part of the problem, as the underlying code may still have to change to support database changes. Coding validation rules in DLLs apart from the rest of the system allows you to update the rules without rebuilding the entire application, but you have to stop the application to replace the DLLs. In addition, the inherent lack of Type safety in calling DLL methods and having to load them using LoadLibrary and GetProcAddress results in code that is difficult to understand and maintain.

.NET makes this task easier. At Brierley & Partners we've developed a set of classes and interfaces to perform data validation in a fraction of the time it would take using traditional C++ and/or COM components. In this article I'll show you how we can update our business rules on a moment's notice without having to shutdown the application, allowing us to react quicker to changing business conditions.

.NET Reflection Is the Key
One of the many advantages to developing systems in .NET is the System.Reflection namespace classes.

Take a look at this sample code to dynamically determine information about a Type at run time:

Assembly assembly = Assembly.Load(strAssemblyName); Type[] arrTypes = assembly.GetTypes(); foreach (Type t in arrTypes) { MethodInfo[] arrMI = t.GetMethods(BindingFlags.Public| BindingFlags.Instance| BindingFlags.DeclaredOnly); foreach (MethodInfo mi in arrMI) { ParameterInfo[] arrPI = mi.GetParameters(); foreach (ParameterInfo pi in arrPI) { Console.WriteLine(pi.Name); } } }

The code uses an assembly object to call the GetTypes method to return all the Types contained in this assembly. Using each Type you can query for Type information including constructors, methods, interfaces, abstraction, and other information. All this information is stored in the assembly's manifest, which is created at compile time. The .NET reflection classes query the assembly's manifest for information about what is contained in the assembly.

Another important class, System.Activator, contains methods to create types of objects locally or remotely, or obtain references to existing remote objects. You can use the information obtained using reflection to dynamically create an instance of a class located in an external assembly. Once you've created that instance you can call any public method passing the information retrieved.

int param = 2; Object[] objCtorArgs = new Object[] {param}; Class MyClass = (MyClass) Activator.CreateInstance(type, objCtorArgs);

Now that you have an instance of the class you can call any method contained in that class. However, doing so requires that you know in advance the name of the method and its signature. .NET provides another way to invoke members from an instance: the Type class.

System.Type, the root of all reflection operations, represents a Type inside the system. System.Type is an abstract base class that allows multiple implementations. The system will always provide the derived class' RuntimeType. In reflection, all classes beginning with the word "Runtime" are created only once per object in the system and support comparison operations.

Using the Activator class and the Type class you can create an instance of a specific Type and invoke a member.

int param = 2; Object[] objCtorArgs = new Object[] {param}; object MyClass = Activator.CreateInstance( type, objCtorArgs); object [] args = new object [] {100.09, 184.45}; object result; result = typet.InvokeMember ("ComputeSum", BindingFlags.Public | BindingFlags.InvokeMethod, null, MyClass, args)

This sample will invoke a method called ComputeSum on an instance of the specified Type contained in an assembly.

The .NET Framework provides a series of classes that make it easy to load external assemblies, query the assembly manifest for Type information, create instances of objects of those Types, and invoke members. To get all of this necessary information into the application, you still have to compile the application. We need a level of abstraction to allow the application to know what methods to call and their associated parameters at run time instead of compile time.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date