Monday, April 13, 2009

A DSL for IoC Configuration

Just kind of thinking out loud here... Seems like a fantastic use for an M grammar! Hmm...

// Include file from assembly resource
include res://CWS.SoCHelp.NHibernate/Basic.config

// Include file from C: drive
include file:///C:/Users/sherwooda/Documents/Visual%20Studio%202008/Projects/CWS.SoCHelp.Tests/Extended.config

// Include file relative to executable
include file://~/Fluent.config

// Declare aliases for namespaces and assemblies
alias SoCHelp (CWS.SoCHelp, CWS.SoCHelp);
alias NHibernate (CWS.SoCHelp, CWS.SoCHelp.NHibernate);
alias Tests (CWS.SoCHelp.Tests, CWS.SoCHelp.Tests);

// Basic configuration, map service to type, default to "singleton" with no name
SoCHelp:IUnitOfWorkFactory -> NHibernate:NHibernateUnitOfWorkFactory;

// Map open generic with transient instance and no name
SoCHelp:IRepository`1 -> NHibernate:NHibernateRepository`1 transient;

// Don't use aliases, map exact type specified
"CWS.SoCHelp.IUnitOfWorkFactory, CWS.SoCHelp" ->
"CWS.SoCHelp.NHibernate.NHibernateUnitOfWorkFactory, CWS.SoCHelp.NHibernate" singleton;

// Specify an identifier for a service
$Command = Tests:ICommand -> Tests:Command singleton;

// Map specialized generic
$UserRepo = SoCHelp:IRepository`1[[Tests:User]] -> Tests:UserRepository transient;

// Parameters specified
$RedBookFinanceRetriever = Tests:IRetriever -> Tests:HttpRetriever singleton
{
url = "http://www.megacorp.com/financials/redbook.csv";
timeout = 3000;
}

$BlueBookFinanceRetriever = Tests:IRetriever -> Tests:HttpRetriever singleton
{
url = "http://www.megacorp.com/financials/bluebook.csv";
timeout = 3000;
}

// Refer a dependency to a previously created component
$ExternalFinancialProcessor = Tests:IProcessor -> Tests:AuditProcessor
{
retriever = $BlueBookFinanceRetriever;
}

$InternalFinancialProcessor = Tests:IProcessor -> Tests:AuditProcessor
{
retriever = $RedBookFinanceRetriever;
}

// Declare a bunch of commands
$JumpRope = Tests:ICommand -> Tests:JumpRope;
$PickUpSticks = Tests:ICommand -> Tests:PickUpSticks;
$Honk = Tests:ICommand -> Tests:Honk;

// Pass an array of components to a dependency
Tests:IProcessor -> Tests:CommandProcessor
{
commands = [$JumpRope, $PickUpSticks, $Honk];
}


No comments: