Feeds:
Posts
Comments

Reflection is one of the features of .Net that when used with care can provide great power and flexibility. Its use is often discouraged as being “slow”, though it’s used to enable many features of .Net that are core to .Net’s power. It’s as though Reflection is “good” when the framework uses it without the need to get our hands dirty, but “bad” if we actually dare use it directly. Sure, it’s slower then using typed references. But what is too “slow”? Does a solution using Reflection make it impossible to meet your performance requirements? Do you have a formal performance requirement?

There are some solutions that can be implemented quite easily with Reflection that would be painful to do without. One thing about Reflection that often got in my way is its complexity. Like many powerful features there’s a lot of options to consider when Reflecting. Or is there? While there are all kinds of things you CAN do, there’s probably a very small subset that you’ll actually need 90% of the time.

So how to make life easier? Certainly a nice Facade to simplify the API, but I never really had one I liked/was comfortable enough with to use Reflection regularly.

Enter extension methods. Using some simple extension methods I now have a Reflection Facade that is natural and trivial to use. One day I was doing some Javascript work and really enjoying the simplicity of statements like

for (prop in myObj) { fn( myObj[prop] ); }

to operate on all the properties of an object. I wanted to be able to do something similar in .Net. The first order of business was to easily get all properties of an object

using System; using System.Reflection; using System.Collections.Generic; using System.Linq; namespace Extensions.Reflection { public static class ObjectExtension { public static IEnumerable Properties(this object obj) { BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty; var propInfos = obj.GetType().GetProperties(flags); return (from property in propInfos select property.Name); } } }

That will allow the following on any object

using Extensions.Reflection; ... for (var prop in myObj.Properties()) { ... }

Next let’s get a property’s value :

public static object Properties(this object obj, string property) { BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty; var propInfo = obj.GetType().GetProperty(property, flags); return propInfo.GetValue(obj, flags & BindingFlags.GetProperty, null, null, null); }

to get us to

for (var prop in myObj.Properties()) {
  fn( myObj.Properties(prop) );
}

Because PropInfo.GetValue returns an object it may be necessary to cast the return value in the caller. So let’s add one more method that can be used if the return type is known.

public static T Properties<T>(this object obj, string property) { BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty; var propInfo = GetPropertyInfo(obj, property, flags); return (T) propInfo.GetValue(obj, flags & BindingFlags.GetProperty, null, null, null); }

Now, you’ll probably only use Properties<T> in specialized cases. If you’re going to call it with a known return type at design time you probably also know the property name and should call the property directly. But suppose you have a special generic method that you know will be calling a String property, but you won’t know which object or property until run-time. Properties<String> could be used to Reflectively get the property value without having to cast in the calling code.

Finally, let’s set the property’s value

public static object Properties(this object obj, string property, object value) { BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty; var propInfo = obj.GetType().GetProperty(property, flags); object result; if (propInfo.CanWrite) { propInfo.SetValue(obj, value, null); result = value; } else { result = propInfo.GetValue(obj, flags & BindingFlags.GetProperty, null, null, null); } return result; }

This extension method takes the property name and a value to set the property to. This implementation returns the value just set. Now, the property may be read only, in which case the method returns the current value of the property instead of the new value. You may want different behavior, but it works for me. There’s no error and I can compare the new and returned values to see if they’re different and decide what to do next.

Now, setting a value isn’t quite as nice as the associated Javascript, but it’s quite servicable.

Javascript:

for (prop in myObj) { myObj[prop] = aValue; }

.Net :

for (var prop in myObj.Properties()) { myObj.Properties(prop, aValue); }

Now this code ignored any Reflection exceptions for the sake of brevity. You may want to handle situations where the property doesn’t exist on the object. But it doesn’t complicate it much to add such code.

Reflection can do much more if you need it. You can access protected and private methods if you want, but do you need to (should you) most of the time? No. In keeping with C# conventions the property names are case sensitive, but you could use the BindingFlags.IgnoreCase flag to be more VB like.

What ever your need, these simple methods make Reflection much easier to use. If you don’t need reflection, no problem. But when it would make life easier, just add using Extensions.Reflection; and you have full intellisense at your finger tips, property reflection on every object and a simple API.

I like to use Reflection where it makes the job easier, code simpler and let’s me get things done quickly. Where it proves to be responsible for a performance issue I will re-work just that part to not use Reflection.

Fun with FIPS

As security becomes more and more of a concern it’s likely more companies will start enforcing the FIPS policy.  What’s FIPS you ask, Federal Information Processing Standard.  This happened recently at work and was a whole lot of fun.  FIPS specifies what cryptography providers are acceptable for use, and when the FIPS policy is enforced by Windows any attempt to instantiate a non-compliant .Net provider results in an exception.  Don’t think you use cryptography?  If you create Asp.Net apps then think again.  MachineKey in the *.config file specifies the cryptography algorithm used to hash/encrypt view state.  Don’t use viewstate, do you debug your web apps?  Cryptography!  So after the policy went into effect we couldn’t run web apps, or debug them, or compile them.  Good times.  A morning of Googling got things working again.  So in one convenient location here’s what worked for me.  (These changes are intended for your development workstation.  Some changes may also be needed for test and production servers.)

1. The default cryptography algorithm, AES, is not compliant, SHA1, DES and 3DES are:

<machineKey decryption=3DES /> <!– or DES –>

2.  Edit devenv.exe.config, assuming a default install it’s in Program Files\Microsoft Visual Studio 9.0\Common7\IDE\, and add


<configuration>
    <runtime>
        <enforceFIPSPolicy enabled="0" />
This allows VS to compile the application.

3. Open, or create, file Program Files\Common Files\Microsoft Shared\DevServer\9.0\WebDev.WebServer.EXE.config and add

<?xml version ="1.0"?>
<configuration>
    <runtime>
        <enforceFIPSPolicy enabled="0" />
    </runtime>
</configuration>

This allow the web server to compile and run apps with   <compilation debug=true>.

Another curious thing happened once the FIPS policy was enforced, the DocProject add-in wouldn’t load when I started VS.  Once enforceFIPSPolicy was disabled in devenv.exe.config it started working again.  It must load a crypto provider, but how and why it uses cypto I don’t care.  I just want it to work.

That got me thinking.  How do we protect our own applications from changes like this?  Knowing what I know now from this little escaped, if you use cryptography in any way then the user should be able to easily configure the provider to use.  And when the code fails because a provider isn’t acceptable to some policy the error message should be very clear why and what to do about it.

Every time VS failed to compile a class the Error window brought me to an import of either Microsoft.VisualBasic or System.Xml.Serialization.  Leading me to believe there was a problem with …. Microsoft.VisualBasic or System.Xml.Serialization.  A wild goose chase that was.

Even if you’re encrypting or hashing things for purely internal reasons, never to see the light of day, once the FIPS switch is flipped the whole thing will blow up the first time you create that provider.  It doesn’t matter if you’re encrypting bank records to ship around the world or just want some funny strings, it won’t work anymore.  Your customers won’t be very happy when that day comes.  And if you sell or provide services to the Government you can expect to encounter this.

Beyond cryptography, anything that deals with security or sensitive information could be a candidate for replacement, authentication and authorization methods, ACL policy, password policy, etc.  Sometimes a customer may not like a lack of flexiblity but will accept it, but sometimes it’s mandated from a higher authority and there’s little choice.