Category Archives: reflection

One of the compelling directions beyond ‘the basics’ of domain-driven development is the advent and increasing use of ‘DSL’ (Domain Specific Language) technology in .NET. We have had a rich set of features since the 2005 release of Visual Studio in the Guidance Automation Toolkit and the DSL Toolkit and these have become even more compelling. I wrote about this back in January, 2006 as published here. However for some needs, the language now may provide enough for many smaller cases.

Keep in mind, this post is not focused on DSL topics (one any developer cannot really afford to miss now), so one could debate the merits of the link I make. My argument is this:

My definition of a DSL is very simply :

A Domain Specific Language is a way, typically using a combination of visual and textual methods, or just textual, to solve a limited but typically non-trivial set of problems. It is typically a smaller stand-alone ‘language’ or language-extension to a larger more horizontal language such as C# (the point I make here is C# has evolved to allow you to expand C# with DSLs you write in C#. This is very different the the DSL Toolkit and I have never had this opinion until I finally got to be immersed deeply in functional style programming enhancements to C# and the ease of extending just about any API with extensions..

I continue the discussion of what a DSL is here. I will be adding to this section of the site over time but if you just want the listed info, no need to go on a tangent now.

Now that new .NET 3.5 C# 3.0 features are allowing us to make the Framework API of .NET work in ways not present ‘out of the box’ the scope of what is possible can be deep and broad.

Part 1 : The DSL Perspective – A Real Example

I’ll use a project we are working on now, which is quite specifically aimed to

  • Minimize the configuration overhead of using an Inversion of Control container
  • Provide the benefit of ‘provider/container’ independence
  • Allow the consumer to change ‘container provider’ vendors with a simple change in ‘meta configuration’

In other words, we are trying to create an abstraction on top of an abstraction, as we believe this particular area is now mature enough (and indeed this is how software engineering historically more then not progresses over time) to do so.

This project has no intention of BEING an inversion of control container nor a dependency injector, rather its aim is to allow people to make use of these critical concepts in much easier ways while eliminating hesitation related to provider lock-in.

It’s no secret we are massive fans of the work of the Castle Project and they are indeed the first ‘plug-in’ adapter we are on schedule to deliver. However the architecture (something this post is NOT trying to explain) of our solution models the DOMAIN of this area, and is not specific to any particular offering (although to be blunt I would say if any bias existed it would be from the conceptual framework that exists now in the Windsor Container/MicroKernal trunk).

A domain specific example

In the area of ASP.NET one technique for loading our solution into memory is via the IHttpModule implementation we provide. Here is what the custom global.asax.cs code looks like:

public abstract class IntegrationPoint : HttpApplication, IDomainApplication {

private static IZeroConfigDI _container;

/// <summary>
/// Executes custom initialization code after
/// all event handler
/// modules have been added.
/// Also acquire a reference to the HttpModule
/// for IoC / DI if present as a module
/// </summary>
 
public override void Init() {        

        _container = Modules.GetIoCModule();
          base.Init();
}

The interesting areas which are not provided by Microsoft include:

  1. IDomainApplication interface
  2. IZeriConfigDI Interface static reference
  3. Modules.GetIoCModule()

The first two have more to do with our solution then the topic of this post, so I’ll focus on #3.

As this code is inside the HttpApplication, we have access to the Modules property which is read-only. Here is the documentation:

 

System.Web.HttpModuleCollection Modules { get; }


Member of System.Web.HttpApplication


Gets the collection of modules for the current application.
Returns:
An System.Web.HttpModuleCollection that contains the names of the modules for the application.

Your first reaction if your familiar with this collection is that it does not have anything even close to the GetIoCModule() method we are calling above.

Indeed this is our ‘domain specific’ extension to the .NET Framework API (one of many for this solution).

Here is the implementation of this ‘DSL’ extension:

/// <summary>
///
Provides ‘DSL specific’ extensions to the ASP.NET environment for
/// the IoC Zero Config environment which is not new (after all this becomes a static)

/// </summary>
/// The entire point for extension methods is ‘Fluency in API’ as it allows ‘shorthand’ code

public static class ZeroConfigInstanceResolver {

private const string ZeroConfigTypeString = "IoCConfigModule.IHttpModel";

 /// <summary>
///
Gets the IZeroConfigDI reference
///
(using domain specific logic and the 
///
generic logic extending the container)
/// </summary>
/// <param name="container">The container.
</param>
/// <returns></returns>

public static IZeroConfigDI GetIoCModule(this HttpModuleCollection container) {

                        return
                              container.FindInstance(
                                () =>
                                        container.Get(ZeroConfigTypeString)
                                                  
 as IZeroConfigDI);

}

As you can see above we are very specific in our intent to add this to the HttpModuleCollection. There is nothing that interesting above except for the method call FindInstance(Func<TResult>) off the target ‘container’. This is a peek into the non-DSL related extension that represents. You might be aware that there is no such FindInstance available off the HttpModuleCollection.

One of our many goals in creating a fluent, easily used API is reducing complexity and providing very maintainable code. Here you can see the Lambada expression required to locate our service is hidden from the developer completely, yet this code is not a ‘one-off’ as we have provided both a DSL level extension in concert with a far more generic extension.

Part 2: Extending the Horizontal to Empower the Domain Specific

In looking at the HttpModuleCollection, and in our desire to facilitate other sources of resolving our module, it inherits from the abstract parent NameObjectCollectionBase.

Here is the definition of what inherits from this abstract parent:


public abstract class NameObjectCollectionBase

Member of System.Collections.SpecializedSummary:

Provides the abstract base class for a collection of associated System.String keys and System.Object values that can be accessed either with the key or with the index.

The issue arises as this abstract base leaves it up to its concrete implementer to provide the indexer (or say Get() method) to access the object desired. Therefore a nice way to enhance this abstract type to work across all of the children is to literally pass in the method to resolve the object desired.

Part 3 : The Generic Extension

Here is the trivial extension method used to ‘open up’ the NameObjectCollectionBase and which is used above:

/// <summary>
///
Finds the instance in the NameObjectCollectionBase
/// using the Functor
/// </summary>
/// <typeparam name="TContainer">
The type of the container.</typeparam>
/// <typeparam name="TResult">
The type of the result.</typeparam>
/// <param name="container">
The container.</param>
/// <param name="finder">
The finder.</param>
/// <returns></returns>
public static TResult FindInstance<TContainer, TResult>
       (
this TContainer container, Func<TResult> finder)
              where TContainer : NameObjectCollectionBase where TResult : class {


                    return finder();

}

Since we cannot abstract up the get method, we take a page from Functional Programming and literally pass in the code to execute (which we do above).

A common pattern is to expose methods like the above, but add additional versions that allow more parameters into the Func<TResult>. This is well covered well by many of the Linq references and books available.

Part 4: How this allows us to embrace deep/wide change

A simplistic example is supporting the acquisitions of our target reference (IZeroConfigDI) if it is set as ApplicationState or as an IHttpModule. We could make the design decision to allow our find method to reside literally as an extension method of our HttpApplication (and indeed this turns out to be a reasonable choice as the valid inheritors from NameObjectCollectionBase are sealed and therefore invalid as generic constraints). Here is one approach (not ideal and not our final code but this illustrates the point.) Why not offer your optimized solution?

CODE:

public abstract class IntegrationPoint : HttpApplication, IDomainApplication {

private static IZeroConfigDI _container;

/// <summary>
///
Executes custom initialization code after
/// all event handler
/// modules have been added.
/// Also acquire a reference to the HttpModule
/// or Application State
/// for IoC / DI if present
/// </summary>
public override void Init() {

                  _container = this.GetIoCModule(); base.Init();

}

And the extension on HttpApplication:

public static class ZeroConfigInstanceResolver {

private const string ZeroConfigTypeString = "IoCConfigModule.IHttpModel";

/// <summary>
///
Gets the IZeroConfigDI reference if possible (null if not found)
/// using domain specific logic and the
/// generic logic extending the container.
/// </summary>
/// <param name="container">
The container.</param>
/// <returns></returns>
public static IZeroConfigDI GetIoCModule(this HttpApplication container) {

                       var modules = container.Modules;
                      
var applicationState = container.Application; 
                     

                        var resultVar = modules.ToInstance(
                                   () => modules.Get(ZeroConfigTypeString)
                         )
        
               ?? 
                        applicationState.ToInstance(
                                   () =>
applicationState.Get(ZeroConfigTypeString)
                         );

                       return resultVar as IZeroConfigDI;

}

No change is required on the extension to the FindInstance extension.

Can you see how the above can be improved?

We expand this to make the ‘rule for finding the IZeroConfigDI external. To be specific, above we have a business rule implemented that we typically would not want ‘hard coded’. In fact more then not all things considered we want this. So we do the4 following:

  • Determine the Delegate signature for the business rule.
  • For the above, we need as input (at a minimum) an HttpApplication instance as that is the container for the models and state, and those two items lack a shared interface or base (or we could use that).
  • The signature returns (in all cases) an instance cast where it implement IZeroConfigDI to resolve this business rule.
  • Therefore the business rule signature is Func<HttpApplication ,IZeroConfigDI>

 

  • It’s an essential skill to not only master generics at the deepest level, but to master all the intrinsic delegate types (Predicate, Func, Action, etc.) to be proficient in the state of the technology of Linq today

  • We wish it was easier to ‘extend’ Delegates by inheritance or to not be tasked with coding to each variant of a delegates possible type parameters, but this is different the Object Oriented in it’s domain.

  • We also wish the generic constraint language would be fundamentally focused on, extended and evolved to allow the full richness in constraint semantics as we have with Linq Expressions.