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

    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

    Digitally Signing Business Objects

    I’m in the process of working on a Smart Client application that works with Business Objects.  All Business Objects implement the following interface:

    public interface IBusinessObject
    {
        int ID { get; }
        byte[] Signature { get; set; }
        byte[] ConcurrencyCheck { get; }
    
        // Other properties here
    }

    As you can see, each BO has a unique ID integer associated with it.  This value is used for many things. I want to ensure that a malicious user can not modify this value and present the hacked BO to the server.  To verify the integrity of the BO I decided to digitally sign it using the value of the ID property.  This can be done with the following code:

    public static void Sign(IBusinessObject instance)
    {
        Sign(instance, instance.ID);
    }
    
    public static void Sign(IBusinessObject instance, int id)
    {
        if (instance == null)
            throw new ArgumentNullException("instance");
    
        SHA1 sha = new SHA1CryptoServiceProvider();
        byte[] hash = sha.ComputeHash(BitConverter.GetBytes(id));
        DSASignatureFormatter DSAFormatter = new DSASignatureFormatter(DSAProvider);
        DSAFormatter.SetHashAlgorithm("SHA1");
        instance.Signature = DSAFormatter.CreateSignature(hash);
    }
    
    public const int ExpectedSignatureLength = 40;
    
    public static bool IsValid(IBusinessObject instance)
    {
        if (instance == null)
            throw new ArgumentNullException("instance");
    
        if (instance.Signature == null || instance.Signature.Length != ExpectedSignatureLength)
            return false;
    
        SHA1 sha = new SHA1CryptoServiceProvider();
        byte[] hash = sha.ComputeHash(BitConverter.GetBytes(instance.ID));
        DSASignatureDeformatter DSADeformatter = new DSASignatureDeformatter(DSAProvider);
        return DSADeformatter.VerifySignature(hash, instance.Signature);
    }

    The nice thing is that the DSASignatureFormatter class will automatically salt the generated signature.  It is important to note that the “DSAProvider” variable above be a static variable within the class.  This is needed in order to ensure that it is loaded with a constant key value so that, when a BO is verified at some point in the future, the check will succeed for previously issued signatures.  I accomplish this by loading the key using the “FromXmlString” method in the static constructor for the host class:

    public static readonly DSACryptoServiceProvider DSAProvider;
    
    static SecurityHelper()
    {
        DSAProvider = new DSACryptoServiceProvider();
        DSAProvider.FromXmlString(KeySet);  // Value obtained from ToXmlString
    }

    Categories: C#
    Posted by Beau on Sunday, August 24, 2008 1:29 PM
    Permalink | Comments (0) | Post RSSRSS comment feed

    Code Generators that rely on databases

    I hate them.  Well, OK, maybe “hate” is a little strong but lets just say that I don’t like them.  I have used CodeSmith, the Kinetic Framework (newly renamed), and numerous others.  One thing I have noticed is that almost all of them are heavily dependent on the database.  By that I mean that they are ORM-based code generators where the objects are created from the relational database schema.  Over the last two years I have spent the majority of my “development free time” researching code generation techniques.  I have looked at many, many tools.  I have built my own tools.  I have built my own parsers, generators, etc.  I won’t go into full detail in this post about my lessons learned but, suffice it to say, I have come full circle on many topics. 

    I have recently embarked on yet another new approach that, I hope, will be my last.  One thing I must point out is that my generator is for developers.  Now you might say that CodeSmith is for developers, who else would it be for?  Well, to be honest, a tool like CodeSmith adds a lot of “fluff” that I really don’t care about.  I don’t care about IDE integration, syntax highlighting, etc.  I do care about Intellisense.  In all reality, my generator has all of these things too -- I just get it for free.  My generator works on two main principles: 

    1) Use the compiler as much as possible.
    By this I mean that I do not parse templates or read anything from XML files.  Everything in the entire “generation context” is compiled.  I am a Reflection freak, so I make heavy use of that.   This complexity, however, is hidden from the developer doing the code generation.  Also, for extensibility, I make heavy use of extension methods and design patterns.

    2) The database is not the “source of truth”
    The source is preserved and maintained in code.  I cannot even begin to touch on the problems that using a database as your generation source causes.  You will run into problems and limitations.  As you add more and more detail into your generation context, things will get more and more complex and become harder to maintain.  Even if you have the luxury of building a new application and database from scratch, you will run into problems.  Most code generators are able to get you close.  Once you push them past their natural limitations then your templates start to bloat and become very hard to maintain.  They become monolithic and highly coupled.  With my approach I am trying to minimize those things and raise the level of maintainability.  I am trying to take what is actually generated further and decrease the required manual interaction.  Also, I want to increase reusability of templates.  This, dare I say, is trivial with strongly objectified generation approach.

    The reality is that most databases a developer encounters have been around for awhile.  They are ugly.  They have varying levels of normalization.  If you are in this situation and you’re using a code generator that relies directly on the database schema then, well, good luck with that.  More on that later.


    Categories: Code Generation
    Posted by Beau on Saturday, August 09, 2008 11:31 AM
    Permalink | Comments (0) | Post RSSRSS comment feed