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 2010

    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

    Entity Framework - Generating SSDL, CSDL, and MSL

    If you do not want to use the Visual Studio designer to generate your Entity Framework schema files you can use edmgen instead.  I spent some time poking around this application in Reflector and found out what’s involved.  You can use this code to generate the Entity Framework schema files directly yourself.

    Note: You will first need to reference the "System.Data.Entity.Design" assembly and namespace.

    Generating the SSDL file:

    const string Provider = "System.Data.SqlClient";
    const string ConnectionString = "server=.;database=MyDatabase;integrated security=true;";
    const string Namespace = "Testing";
    
    var generator = new EntityStoreSchemaGenerator(Provider, ConnectionString, Namespace);
    generator.GenerateStoreMetadata();
    generator.WriteStoreSchema(@"D:\temp\storeSchema.ssdl");
    var storeEntityContainer = generator.EntityContainer;

    Generating the CSDL and MSL files:
    const string Namespace = "Testing";
    const string ContainerName = "MyContainer";
    
    EntityModelSchemaGenerator generator = new EntityModelSchemaGenerator(storeEntityContainer, Namespace, ContainerName);
    generator.GenerateMetadata();			
    generator.WriteModelSchema(@"D:\temp\modelSchema.csdl");
    generator.WriteStorageMapping(@"D:\temp\storageMapping.msl");


    Generate Classes:

    private static void GenerateObjectLayerCode(string csdlFile, IEnumerable additionalSchemas)
    {
    	var generator = new EntityClassGenerator(LanguageOption.GenerateCSharpCode);
    	var reader = XmlReader.Create(csdlFile);
    	var writer = new StringWriter();
    	generator.GenerateCode(reader, writer, additionalSchemas);
    	string code = writer.GetStringBuilder().ToString();
    }

    The disappointment is that the extensibility for generating the classes in the last step is extremely limited. You only have two options – implement event handlers that fire when a Type and/or Property is created.  The problem is that the TypeGeneratedEventArgs and PropertyGeneratedEventArgs classes passed to your event handler are extremely limited.  For the properties you are not passed the entire CodeDOM CodeMemberProperty instance.  Instead you are only allowed to add additional get/set statements.  You have no way of completely customizing the property definition. In a future post I plan to explore the usage of NRefactory to accomplish this.

    Posted by Beau on Saturday, February 21, 2009 3:00 PM
    Permalink | Comments (2) | 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