190 likes | 332 Views
Dive into the world of IronRuby with Rob Rowe as he outlines a powerful approach to generating .NET assemblies without traditional compilation. This guide covers the essentials, from establishing assembly characteristics to creating classes, properties, and methods dynamically using IronRuby. Learn to leverage .NET libraries like System.Reflection.Emit, streamline tedious coding tasks, and integrate data-driven code generation into your applications. Suitable for developers looking to enhance their Ruby skills while working within the .NET framework.
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)