beaucrawford.net

Give me data or give me death

About the author

Author Name is someone.
E-mail me Send mail

Recent comments

Don't show

Authors

Tags

Don't show

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2012

    Calling TryParse Dynamically

    Most of the common types have a “TryParse” method available.  Here’s a method you can use to dynamically call the corresponding TryParse method for a specific Type:

    public static T ConvertValue<T>(string stringValue)
    {
        if (typeof(T) == typeof(string))
            return (T)Convert.ChangeType(stringValue, typeof(T));
    
        var type = typeof(T);
    
        bool nullableType = type.IsGenericType 
            && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>));
    
        if (nullableType)
        {
            if (stringValue == null)
                return default(T);
    
            type = new NullableConverter(type).UnderlyingType;
        }
    
        Type[] argTypes = { typeof(string), type.MakeByRefType() };
    
        var tryParse = type.GetMethod("TryParse", argTypes);
    
        if (tryParse == null)
        {
            string exceptionMessage = string.Format("A method named 'TryParse' does not exist for the '{0}' Type.", type.FullName);
            throw new InvalidOperationException(exceptionMessage);
        }
    
        object[] args = { stringValue, null };
    
        bool successfulParse = (bool)tryParse.Invoke(null, args);
    
        if (!successfulParse)
            throw new InvalidCastException();
    
        return (T)args[1];
    }



    I’m currently using this in a code generation scenario where I have a string value and “T” is known at generation time.  Enjoy.


    Categories: C# | Reflection | Code Generation
    Posted by Beau on Tuesday, March 24, 2009 7:35 PM
    Permalink | Comments (3) | Post RSSRSS comment feed

    Hacking into the Windows Workflow Rules Engine

    On my current gig we have been toying with the idea of creating a rules engine to a control a simple work flow that centers on Microsoft Message Queue.  The main idea is to build a very simple UI that allows a Business user to enter an expression based off of a Type in our system, such as ICustomer.   We would give the user some sort of “Poor Man’s Intellisense” to help them with the syntax but, other than that, they would be on their own – just keep pressing keys until you have a valid expression (we would wrap the expression evaluation call in a try/catch).

    My first thought was to use the LINQ Dynamic Query API to allow a user to enter a statement as a string and then simply call some code that looks something like this:

    var lambda = DynamicExpression.ParseLambda(typeof(ICustomer), typeof(bool), txtExpression.Text.Trim());
    var result = (bool)lambda.Compile().DynamicInvoke(instance);

    The statement, in this case, would evaluate to a Boolean value (the conditional part of the Rule evalulation).  That looked very promising and definitely would have fit the bill for the vast majority of our needs. I wanted something more though – namely the ability to use extension methods as part of the expression and to also be able to execute method invocation statements.  I was not having any luck in modifying the LINQ Dynamic Query code to consistently do what I needed to for these items.  That led me to look elsewhere.

    I had previously heard about using the WF Rules Engine outside of WF itself at the Twin Cities Code Camp a few months ago.  It’s a pretty simple concept really and I remember thinking at the time that it looked very promising.  In an effort to pay this problem its due diligence I investigated WF in more detail.  Turns out it’s pretty easy to interact with the Rule object model directly:
    var thisType = typeof(IShipment);
    
    var currentInstance = new Shipment();
    
    var ruleSet = new RuleSet("Test");            
    var ruleValidation = new RuleValidation(thisType, null);
    
    Rule rule = new Rule("Rule 1");
    rule.ReevaluationBehavior = RuleReevaluationBehavior.Never;
    rule.Condition = Parser.ParseCondition("ShipmentDate > DateTime.Now.AddDays(-30)", ruleValidation);
    rule.ThenActions.AddRange(Parser.ParseStatementList("Queue.Send(\"StagingQueue\", this)", ruleValidation).ToArray());
    
    ruleSet.Rules.Add(rule);
    
    RuleExecution exec = new RuleExecution(new RuleValidation(currentInstance.GetType(), null), currentInstance);
    ruleSet.Execute(exec);

    The crux of my problem is obviously how to parse an arbitrarily complex expression into an an instance of RuleExpressionCondition.  If you look at the above code you will notice some references to a static class named “Parse”.  This, unfortunately, is a class that I had to create.  I noticed that WF uses the System.Workflow.Activities.Rules.Design.RuleSetDialog Windows Form to maintain a RuleSet.  I cracked this Type open in Reflector in an effort to see how they were taking the strings entered on the UI and converting them to expressions.  As I expected, the functionality for doing this is all internal.  Bummer.  Well, for now, I decided to use a little Full Trust reflection to create a wrapper around some Reflection calls:

    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Workflow.Activities.Rules;
    
    namespace WFRulesSample
    {
        public static class Parser
        {
            private const string TypeName = "System.Workflow.Activities.Rules.Parser, System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
    
            public static RuleExpressionCondition ParseCondition(string expression, RuleValidation ruleValidation)
            {
                return ExecuteMethod("ParseCondition", new object[] { ruleValidation }, new object[] { expression }) as RuleExpressionCondition;
            }
    
            public static List< RuleAction > ParseStatementList(string expression, RuleValidation ruleValidation)
            {
                return ExecuteMethod("ParseStatementList", new object[] { ruleValidation }, new object[] { expression }) as List< RuleAction >;
            }
    
            private static object ExecuteMethod(string name, object[] ctorParameters, object[] methodParameters)
            {
                var type = Type.GetType(TypeName);
                var ctor = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(RuleValidation) }, null);
                var instance = ctor.Invoke(ctorParameters);
                var method = instance.GetType().GetMethod(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                return method.Invoke(instance, methodParameters);
            }
        }
    }

    It’s doubtful that the above code will ever see the light of day for this project.  I just found it interesting.

    Caveat – yes, the above code is probably not great in terms of performance.  There are numerous ways you could speed it up with the use of some DynamicMethod calls.  Good luck and happy hacking.


    Categories: Reflection | C#
    Posted by Beau on Saturday, March 14, 2009 1:03 AM
    Permalink | Comments (3) | Post RSSRSS comment feed

    Using Reflection to get inherited properties for an interface

    This will probably throw you for a loop the first time you encounter it.  If you have an interface that derives from another interface and you want to get all of the properties (including those from the parent interface) then you cannot simply call GetProperties (like you can do with classes).

    Example:

    public interface IPerson
    {
        string FirstName
        {
            get;
        }
    
        string LastName
        {
            get;
        }
    }
    
    public interface IManager : IPerson
    {
        int ManagerID
        {
            get;
        }
    
        int DepartmentID
        {
            get;
        }
    }

    If you call typeof(IManager).GetProperties() you will only have access to the properties that are directly part of IManager, i.e. ManagerID and DepartmentID.  If you need all properties, including those from IPerson, then you must use the GetInterfaces method from Type.  Here’s a helper method that does just that:

    public static PropertyInfo[] GetAllProperties(Type type)
    {
        List<Type> typeList = new List<Type>();
        typeList.Add(type);
    
        if (type.IsInterface)
        {
            typeList.AddRange(type.GetInterfaces());
        }
    
        List<PropertyInfo> propertyList = new List<PropertyInfo>();
    
        foreach (Type interfaceType in typeList)
        {
            foreach (PropertyInfo property in interfaceType.GetProperties())
            {
                propertyList.Add(property);
            }
        }
    
        return propertyList.ToArray();
    }

    You can now simply call GetAllProperties(typeof(IManager)) to have all properties returned, including those from IPerson.


    Categories: C# | Reflection
    Posted by Beau on Sunday, September 21, 2008 1:29 PM
    Permalink | Comments (5) | Post RSSRSS comment feed

    Constructor invocation with DynamicMethod

    Justin sent me a snippet for creating a “Fast Activator”.  I modified it a little bit to the following:

    public delegate T FastActivator<T>() where T : class;
    
    public static FastActivator<T> CreateFastActivator<T>(BindingFlags bindingFlags, params Type[] constructorParameterTypes)
        where T : class
    {
        var type = typeof(T);
        var dynamicMethod = new DynamicMethod("___FastActivator" + type.Name, type, null, type);
        var ilGenerator = dynamicMethod.GetILGenerator();
        var constructor = type.GetConstructor(bindingFlags, null, constructorParameterTypes, null);
        ilGenerator.Emit(OpCodes.Newobj, constructor);
        ilGenerator.Emit(OpCodes.Ret);
        return dynamicMethod.CreateDelegate(typeof(FastActivator<T>)) as FastActivator<T>;
    }
    
    public static FastActivator<T> CreateFastActivator<T>()
        where T : class
    {
        return CreateFastActivator<T>(BindingFlags.Public | BindingFlags.Instance);
    }

    Here’s a chunk of code that compares three methods of instantiating a class:

    public static void Time(Action action, string name)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
    
        for (int i = 0; i < 1000000; i++)
        {
            action();
        }
    
        sw.Stop();
        Console.WriteLine(name + ": " + sw.ElapsedMilliseconds);
    }
    
    static void Main(string[] args)
    {
        FastActivator<MyClass> fast = CreateFastActivator<MyClass>();
    
        Time(() => { MyClass m = Activator.CreateInstance<MyClass>(); }, "Activator");
        Time(() => { MyClass m = new MyClass(); }, "Constructor");
        Time(() => { MyClass m = fast(); }, "FastActivator");
    
        Console.WriteLine("Done...");
        Console.ReadLine();
    }


    The output on my box:

    Activator: 1333
    Constructor: 39
    FastActivator: 56

    That’s a decent performance bump over a simple call to Activator.CreateInstance.


    Categories: C# | Reflection
    Posted by Beau on Monday, August 25, 2008 7:42 PM
    Permalink | Comments (0) | Post RSSRSS comment feed

    Injecting an IRenderingExtension instance into the ReportViewer control

    In a previous post I discussed how it is possible to enable HTML rendering for local reports firing via a ReportViewer instance.  I did that because I was recently in a situation where we were using the ReportViewer in local mode had to support HTML reports.  Running reports in local mode with the ReportVIewer affords you many luxuries, but HTML report generation is not one of them.  Desperate times call for desperate measures.

    I also mentioned the fact that rendering extensions, presumably for a good reason, are not extensible by default for local reports.  By “extensible”  I mean that there is no public object model exposed nor are their .config options to alllow, for example, your own custom rendering extension types to be loaded.  Of course, as an absolute last resort, you can use Reflector to disassemble the code and hack into the object model using Reflection.   I will be the first to tell you that this is not a good idea (for a number of obvious reasons) but the main one is that the component’s code can change (a new version comes out, etc).  When that happens, private field names can change and cause your references obtained via Reflection to be null.  That can lead to big problems and hard-to-solve bugs.

    As I looked at the code from my previous post a little more I soon realized that the internal list of rendering extensions holds instances of type Microsoft.ReportingServices.ReportRendering.IRenderingExtension.  With this interface you could create your own extension and then inject it into the internal list using Reflection.

    Here’s some code do that:

       1: private static void AddRenderingExtension(ReportViewer viewer, string formatName, Type renderingExtension)
       2: {
       3:     const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
       4:  
       5:     FieldInfo m_previewService = viewer.LocalReport.GetType().GetField
       6:     (
       7:         "m_previewService",
       8:         Flags
       9:     );
      10:  
      11:     MethodInfo ListRenderingExtensions = m_previewService.FieldType.GetMethod
      12:     (
      13:         "ListRenderingExtensions",
      14:         Flags
      15:     );
      16:  
      17:     object previewServiceInstance = m_previewService.GetValue(viewer.LocalReport);
      18:  
      19:     Type type = Type.GetType("Microsoft.Reporting.LocalRenderingExtensionInfo, Microsoft.ReportViewer.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
      20:  
      21:     ConstructorInfo ctor = type.GetConstructor
      22:     (
      23:         BindingFlags.NonPublic | BindingFlags.Instance,
      24:         null,
      25:         new Type[] { typeof(string), typeof(string), typeof(bool), typeof(Type), typeof(bool) },
      26:         null
      27:     );
      28:  
      29:     IList extensions = ListRenderingExtensions.Invoke(previewServiceInstance, null) as IList;
      30:  
      31:     object instance = ctor.Invoke(new object[]
      32:     {
      33:             formatName,
      34:             formatName,
      35:             true, 
      36:             renderingExtension, 
      37:             true
      38:     });
      39:  
      40:     extensions.Add(instance);
      41: }

    An example call would be:

    AddRenderingExtension(reportViewerInstance, "HTMLOWC", typeof(HtmlOWCRenderingExtension));

    I chose HtmlOWCRenderingExtension simply because it is a type that is not already in the internal list (not sure why) but yet implements IRenderingExtension.  I am not sure of the actual differences between it and its parent type, Html40RenderingExtesion.  As the name alludes to, I assume it deals with OWC (Office Web Components) and some special rendering considerations they have for HTML.  Regardless, if you use the “Derived Types” capability in Reflector you will see that there are a few other Types that implement this interface:

     

    As you can see above, in addition to the Excel and PDF extensions provided by the viewer by default, there are additional extensions available for images (which are available in server reports but not local reports).  You could, of course, code your own implementation and then inject that as well.  At this point, I am not sure of the complexities involved with that.  A rendering extension that would be extremely useful would be one that is able to generate CSV files.  Interestingly enough, server reports have that available as an export option.  Local reports do not.  You can probably guess where I’m going with this…


    Categories: C# | Reflection
    Posted by Beau on Wednesday, July 02, 2008 12:58 AM
    Permalink | Comments (2) | Post RSSRSS comment feed