Thursday, July 30, 2009

DynamicProxy tutorials - Krzysztof Koźmic

Currently looking at DynamicProxy tutorials by Krzysztof Koźmic Any AOP type development is a candidate to be done by DP.

Excellent tutorial series...

Leave the irrelevant standards out of the coding standards...

Coding standards are put in place primarily for maintainability purposes but how far does an organisation/company or induvidual go in relation to coding standards?

Heres my opinion on coding standards: Once the code is some way consistent - that is acceptable enough to me.

Having to define exactly how many lines are between methods, and spacing rules are irrelevant in comparison to the quality of the code that is actually written.

Some open source projects that I have looked at (Castle and NHibernate to name a few) have general coding standards but don't go down to a spacing level.

I recently worked on a project where coding standards were so stringent that we had to run regression tests again due to spacing issues! - The word "practicality" comes to mind

Monday, July 27, 2009

Binsor 2.0 Spike

Recently, I tasked myself with the responsibility of spiking Binsor and checking if my current projects castle configuration (which we have in an XML config file) could be fully converted.

Binsor is a DSL language for Castle Windsor and is a feature offered in the reknowned open source Rhino.Commons assembly. There are quite a few "basic" posts about Binsor but there were a few configuration scenarios that I had to dig deeply for. This post attempts to describe these scenarios and also give an overall verdict of Binsor as a whole.


1. Import statements

You must import all assembly types in a Binsor file e.g.
import Billy.CommonLibraries
import Billy.Application.Facade from Billy.Application.Facade.RC2

Note that if you have a type with a namespace that is different to the assembly name e.g. all types under Billy.Application.Facade, you must specify in the format <namespace> from <assembly name>


2. Properties

Properties are simply represented via boo variable declaration e.g.
<properties>
<p1>00:02:00</p1>
<p2>SampleString</p2>
</properties>

would be represented as:

p1 = "00:02:00"
p2= "SampleString"

3. Comments


All comment lines start with '#' e.g.

# Properties

4. Facilities

Declaring facility usage is simple e.g.

<facility
id="factory_Support"
type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
would be represented as:

facility FactorySupportFacility



5. Components

The following component Billy.CommonTypes.Handler.Default

<component
id="exceptionHandler"
service="Billy.CommonTypes.IHandler, Billy.CommonTypes"
type="Billy.CommonTypes.Handler.Default, Billy.CommonTypes">
</component>
would be represented as:

component "exceptionHandler", Billy.CommonTypes.IHandler, Billy.CommonTypes.Handler.Default




6. Types instantiated using instance fields

The following component configuration for Billy.CommonTypes.SystemClock

<component
id="clock"
service="Billy.CommonTypes.IClock, Billy.CommonTypes"
type="Billy.CommonTypes.SystemClock, Billy.CommonTypes"
instance-accessor="Instance">
</component>
would be represented as:
component "clock", Billy.CommonTypes.IClock, Billy.CommonTypes.SystemClock: 
createUsing Instance



7. Components with parameters


<component
id="exceptionLogger"
service="Billy.CommonTypes.Exception.ILogger, Billy.CommonTypes"
type="Billy.CommonTypes.Exception.Logger.EventLog, Billy.CommonTypes">
<parameters>
<logName>#{exceptionLogName}</logName>
<source>#{exceptionLogSource}</source>
</parameters>
</component>
would be represented as:

component "exceptionHandler", Billy.CommonTypes.Exception.ILogger, Billy.CommonTypes.Exception.Logger.EventLog:
logName = exceptionLogName
source = exceptionLogSource



8. Components instantiated using factories


<component
id="sampleTypeInstantiatedWithFactory"
service="Billy.CommonTypes.IProviderFactory, Billy.CommonTypes"
type="Billy.CommonTypes.ProviderFactory, Billy.CommonTypes"
factoryId="mySampleFactory"
factoryCreate="GetSampleType">
</component>
would be represented as:

component "sampleTypeInstantiatedWithFactory", Billy.CommonTypes.IProviderFactory, Billy.CommonTypes.ProviderFactory"
createUsing @mySampleFactory.GetSampleType



9. Event wiring


<component
id="eventingBroker"
service="Billy.CommonTypes.Eventing.IBroker, Billy.CommonTypes"
type="Billy.CommonTypes.Eventing.Broker, Billy.CommonTypes">
<subscribers>
<subscriber
id="subscriber1"
event="Event1"
handler="OnEvent1Firing" />
<subscriber
id="subscriber2"
event="Event2"
handler="OnEvent2Firing" />
</subscribers>
</component>
would be represented as:

component "eventingBroker", Billy.CommonTypes.Eventing.IBroker, Billy.CommonTypes.Eventing.Broker:
wireEvent Event1:
to @subscriber1.OnEvent1Firing
wireEvent Event2:
to @subscriber2.OnEvent2Firing



10. Startable components


<component
id="myStartableComponent"
type="Billy.CommonTypes.Type1, Billy.CommonTypes"
startable="true">
</component>
would be represented as:

component "myStartableComponent", Billy.CommonTypes.Type1:
@startable = true



11. Transient components


<component
id="myTransientComponent"
type="Billy.CommonTypes.Type2, Billy.CommonTypes"
lifestyle="transient">
</component>
would be represented as:

component "myTransientComponent", Billy.CommonTypes.Type2:
lifestyle Transient



12. WCF client components


<component
id="myWCFClient"
type="Billy.Clients.IClient, Billy.Clients"
wcfEndpointConfiguration="MyClient">
</component>
would be represented as:

component "myWCFClient", Billy.Clients.IClient:
wcfEndpointConfiguration="MyClient"

Conclusion


Excellent overall as it reduced the size of my castle configuration file down to 38% of its original size. The Binsor file is also much more readable and eradicates all the XML fluff! However the downside is that I had to reference the Rhino.Commons assembly. Binsor may get integrated into Castle in a future release so I am nearly more inclined to wait until this happens!

A big thank you to Craig Neuwirt for answering any Binsor questions that I had (via Castle forum)