190 likes | 320 Views
Generating Data Access Assemblies with IronRuby. Rob Rowe Twitter: @ rippinrobr Blog: rob-rowe.blogspot.com. Why?. Make tedious changes easier and quicker Create code based off of data specs from outside sources Wanted to learn Ruby
E N D
Generating Data Access Assemblies with IronRuby Rob Rowe Twitter: @rippinrobr Blog: rob-rowe.blogspot.com
Why? • Make tedious changes easier and quicker • Create code based off of data specs from outside sources • Wanted to learn Ruby • Used IronRuby to access to .NET libraries such as System.Reflection.Emit • Generate a DLL without compilation
What is IronRuby? • An implementation of Ruby 1.8.x • Built on top of .NET’s Dynamic Language Runtime • Allows IronRuby to access .NET objects such as System.Reflectionor any other .NET library • Easy to ‘load’ .NET libraries
Overview Consuming Application – ASP.NET MVC 2 Generated Code – Models DLL and C# Domain/Service layer IronRuby Code – Scripts and class for code generation C# Code – Entity Framework 4 and C# service class SQL SERVER Database – stores field definitions
Creating a .NET Assembly • Establish Assembly characteristics • Create the new Assembly • Define the Module • Create the Class • Create the Properties • Create the backing field • Create the Property • Create Getter • Create Setter • Save the Assembly
1. Establish Assembly Characteristics • Create an instance of the System.Reflection.AssemblyName class • Set Version • Set Name • Can set CultureInfo, Crypto KeyPair among as well as other settings
2. Create the new Assembly • Creates the assembly in memory • The first parameter is the AssemblyName object from step 1. • Second parameter sets the permissions for the assembly. Here we can run it and save it to the file system. • Returns an AssemblyBuilder Object. Used to create the module for the assembly.
3. Define the Module • Each .NET assembly must have at least one module • ‘Container’ for classes, interfaces, etc. • Parameters: • Name of the module • Name of the DLL • false – so no symbols are created
4. Create the Class • @mod_builder is the object returned when we created the module. Creates the class ‘under’ the module • First parameter is fully qualified name of the class • Second parameter is used to set public, static, etc. • Returned TypeBuilder object is used to create the class’s fields and properties.
5a. Create Fields • Must create a field for each property • Creates a private field used by the getter/setters • Uses the class’s TypeBuilder object • Parameters • Defines the name • CLR Type • Sets Access level
5b. Create Properties • Creates the Property’s TypeObject used for getter/setters • Parameters: • Property Name • Says there’s a default value for this property • The CLR Type • Since there are no parameters for our properties we pass in null
5c. Create Getter – Prep Work • Creates the Get method TypeObject • DefineMethod’s parameters • Name of the method • Attributes for the method • Return type (CLR type) • Parameters to the method – none for getter • GetILGenerator - creates the object that is used to create the IL code
5c. Create Getter – Method Body • OpCodes.Ldarg_0 – loads the first argument on the stack which is ‘this’ in our case. • OpCodes.Ldfld – pushes the value of the private field onto the stack. • OpCodes.Ret – the returns the last item on the evaluation stack, the value of the private field.
5d. Create Setter – Parameters • Constructs the Type array needed for the setter’s method parameters • The type added to the list is the CLR type of the property • Need to use a generic list to create the necessary CLR array • Use List<T>’s ToArray method to get around CLR array type issues
5d. Create Setter – Method Body • OpCodes.Ldarg_0 – loads the first argument on the stack which is ‘this’ in our case. • OpCodes.Ldarg_1- loads the setter parameter onto the stack • OpCodes.Stfld – sets the value of private_field to the value of the item popped from the stack. • OpCodes.Ret – adds the return statement.
5e. Finalizing Property Creation • Need to associate the getter and setter with our new property • Use the property TypeBuilder to associate the two method’s TypeBuilder objects with the IL we just created
6. Saving the Assembly • The assembly is saved to the file system by using the AssemblyBuilder object’s Save method • Once it has been saved we can use our new Models DLL like any other assembly.
Resources/Contact Info • Robert.rowe@duke.edu • Twitter: @rippinrobr • Blog: rob-rowe@blogspot.com • Code: https://bitbucket.org/robrowe/ironrubyassemblybuilder • Books: IronRuby Unleashed, Programming Ruby (AKA The Pickaxe Book)