Bootstrapping Your Application From IronRuby
I think one of the best use cases for IronRuby is to use it as an automation tool and scripting platform for your domain application. The first hurdle I had to make this possible was Bootstrapping the application so that it can run from the IronRuby runtime. Among other things we need to initialize StructureMap and AutoMapper. Because you’re executing the IR.exe in it’s own AppDomain, there a couple of thing you have to do first.
Using StructureMap from IronRuby StructureMap can be loaded and accessed from IR without difficulty. But I find the syntax to use generic methods in IronRuby a bit noisy. So I made a simple module that wraps the StructureMap generic methods. We see these used in a minute.
require 'StructureMap'
include StructureMap
#module to hide the IronRuby generic noise
module ObjectFactoryModule
def get_instance type_name
ObjectFactory.method(:get_instance).of(type_name).call
end
def inject(type,instance)
ObjectFactory.method(:inject).of(type).call(instance)
end
def eject(type)
ObjectFactory.method(:eject_all_instances_of).of(type).call
end
def replace(type,instance)
ObjectFactory.method(:eject_all_instances_of).of(type).call
ObjectFactory.method(:inject).of(type).call(instance)
end
end
Config files are your enemy
Because IronRuby runs in its own AppDomain, it is impossible to directly access your config files from IR without some serious hackery. But this it is not impossible to get around this if you encapsulate application settings behind an interface, with the default implementation getting values from configuration files. We have a very simple interface:
You can create a ruby class that implements the IApplicationSettings interface by including the interface.
require 'PropertyRegistration.Common'
include PropertyRegistration::Common
include ObjectFactoryModule
class ScriptingApplicationSettings
include IApplicationSettings
def EventSourceDBConnectionString
return 'Data Source=localhost;Initial Catalog=db;Integrated Security=SSPI'
end
def ViewModelConnectionString
return 'Data Source=localhost;Initial Catalog=db;Integrated Security=SSPI'
end
def FasTrackDbConnectionString
return 'Data Source=localhost;Initial Catalog=db;Integrated Security=SSPI'
end
def CurrentSessionContextClass
return 'thread_static'
end
def ViewModelDefaultSchema
return '[PropertyRegistration_ViewSource].[dbo]'
end
def LoadZipcodeDatabaseData
return false
end
end
Now here’s the cool part we can inject the ruby class into structuremap so that it will be the implementation of IApplicationSettings.
$LOAD_PATH << File.dirname(__FILE__) + "/assemblies"
require 'Rake'
dlls = FileList.new(File.join(File.dirname(__FILE__),"assemblies/*.dll"))
dlls.each {|f|require f}
require 'StructureMap'
require 'ObjectFactoryModule.rb'
require 'ApplicationSettings.rb'
require 'PropertyRegistration.DataLoader'
include ObjectFactoryModule
include PropertyRegistration::DataLoader::Application
include StructureMap
#bootstrapper, loading StructureMap registries and other stuff
BootStrapper.startup
settings = ScriptingApplicationSettings.new
# ejecting IApplicationSettings and replacing with ruby class
replace PropertyRegistration::Common::IApplicationSettings, settings
Now, we have loaded all of our assemblies, Called our bootstrapper to initialize StructureMap and everything else. Then we replaced the default implementation of IApplicationSettings with our Ruby implementation and our application is none the wiser. We can now use the IApplicationSettings from StructureMap as well as any classes that have it as a dependency.
exporter = get_instance(DataLoader::SchemaExporter)
exporter.generate_schema
There was more work involved getting everything to run from Rake, but this is the basic wiring and the other stuff is not really important.
I have bigger plans for using IronRuby with my applications. This was the first step. I’ll post more as my journey continues.
