Expanding-File Resource for Spring.NET

§ May 13, 2009 03:48 by beefarino |

I just had a fun emergency - the crew decided to redirect all configuration sources using environment variables, and while Log4Net supports this quite easily, the spring.net context resource-from-a-URI abstraction does not.  E.g., this will not work:

<spring>
    <context>
            <resource uri="file://%PROGRAMFILES%/myapp/ioc.config" />
    </context>
    ...

Knowing that spring.net can leverage custom resource implementations, I set out to extend the file system resource to expand environment variables.  Turns out to be easy-peasy-lemon-squeezie:

public class ExpandableFileSystemResource : Spring.Core.IO.FileSystemResource
{
    public ExpandableFileSystemResource()
        : base()
    {
    }
    public ExpandableFileSystemResource( string resourceName )
        : base( Environment.ExpandEnvironmentVariables( resourceName ?? String.Empty ) )
    {
    }
    public ExpandableFileSystemResource( string resourceName, bool suppressInitialize )
        : base( Environment.ExpandEnvironmentVariables( resourceName ?? String.Empty ), suppressInitialize )
    {
    }
}

Register the resource implementation via config:

<spring>
    <resourceHandlers>
      <handler protocol="filex" type="MyApp.ExpandableFileSystemResource, MyApp"/>
    </resourceHandlers>
    <context>
            <resource uri="filex://%PROGRAMFILES%/myapp/ioc.config" />
    </context>    
    ... 

 And it just works.  Enjoy!



Why I Hate IServiceProvider

§ February 20, 2009 09:18 by beefarino |

I've worked with a lot of code that uses IServiceProvider as a way to disconnect an object from its dependencies.  I've come to loathe this interface for many reasons and have opted for a systematic pattern of dependency injection.

First reason IServiceProvider sucks: it hides the dependencies of an object while decoupling from them.  What do I mean by that?  Pretend you're using this blackbox component from your code:

public class BlackBoxComponent
{
    public BlackBoxComponent( IServiceProvider services );
    public void DoAllTheWork();
} 

Can you tell what services are going to be requested from the service provider?  Me neither.  Now you need another way to discover what dependencies need to be available to the BlackBoxComponent - documentation, source code, something out-of-band that takes you away from your work at hand.

Compare that with some simple constructor injection:

public class BlackBoxComponent
{
    public BlackBoxComponent( IRepository< Thing > thingRepository, ILogManager logManager );
    public void DoAllTheWork();
}

With this, you know exactly what a BlackBoxComponent needs to do its job just from looking at the constructor.

Second reason IServiceProvider sucks: it adds a lot of code.  Fetching the services is cumbersome at best:

    // ...    
    public BlackBoxComponent( IServiceProvider services )
    {
        thingRepository = ( IRepository< Thing > ) services.GetService( typeof( IRepository< Thing > ) );
        logManager  = ( ILogManager ) services.GetService( typeof( ILogManager ) );
    }
    // ...

Sure you can use some syntactic sugar to work around the typeof'ing and naked casting:

public static class ServiceProviderExtension
{
    public static T GetService< T >( this IServiceProvider serviceProvider )
    {
        return ( T ) serviceProvider.GetService( typeof( T ) );
    }
}

which cleans up the code a bit:

// ...    
public BlackBoxComponent( IServiceProvider services )
{
    thingRepository = services.GetService< IRepository< Thing > >();
    logManager  = services.GetService< ILogManager >();
}
// ...

but you're still stuck having to reach out and grab every dependency you need from the service container - which implies that somewhere, some other piece of code is responsible for filling up that service container:

//...
ServiceContainer services = new ServiceContainer();
services.AddService( 
    typeof( ILogManager ),
    new Log4NetLogManager()
);
services.AddService( 
    typeof( IRepository< Thing > ),
    new ThingRepository()
);
//...

More code to write, all of it unnecessary and obsolete given the state of the art in dependency injection frameworks. 



Automation Framework pt 2: End-to-End Example

§ January 27, 2009 00:03 by beefarino |

Having covered the vision and napkin design of an automation framework for our product's core services, it's time for a working end-to-end example.  My goal is to be able to drive one function of our core product: creating a user account.  In addition, I will drive it from both PowerShell and FitNesse to see how well the framework meets the needs from the initial vision.

Getting to Red

I broke ground with this test:

[Test] 
public void CreateUserAccountCommandExecution()
{
    ICommand command = new CreateUserAccountCommand { Name = "joe" }; 
    bool result = command.Execute(); 
    Assert.IsTrue( result ); 
} 

Simple enough - a textbook command pattern; note:

  • an ICommand interface defines the command contract;
  • at the moment, the only member of ICommand is an Execute() method.  It accepts no arguments and returns a boolean to indicate success or failure;
  • CreatePlayerAccountCommand is a concrete implementation of the ICommand contract;
  • CreatePlayerAccountCommand has a Name property that identifies the user name.

Getting to Green

First thing's first - I need the command contract:

public interface ICommand
{ 
    bool Execute(); 
} 

Then I can implement the concrete CreatePlayerAccountCommand type:

public class CreateUserAccountCommand : ICommand 
{ 
    public string Name { get; set; }  
    public bool Execute() 
    { 
        IUserService clientInterface = new RemoteUserService( "http://beefarino:8089" );  
        Credentials credentials = new Credentials( "user-manager", "password" ); 
        Ticket authTicket = clientInterface.Authenticate( credentials );  
        UserData userProperties = new UserData();  
        userProperties.FirstName = Name; 
        userProperties.LastName = "Smyth"; 
        userProperties.Nickname = Name; 
        userProperties.DateOfBirth = System.DateTime.Now - TimeSpan.FromDays( 365.0d * 22.0d );
         
        string userId = clientInterface.CreateUser( authTicket, userProperties );  
        Ticket userTicket; 
        clientInterface.CreateUserTicket( authTicket, userId,  out userTicket );  
        return null != userTicket;
    } 
} 

I'm not going to discuss this code except to explain that:

  • the logic in the Execute() method performs the minimum amount of activity necessary to create a user account;
  • I'm making assumptions about a lot of the data I need (e.g., the age of the user).  I'm trying to keep the command as simple as unconfigurable as possible, and there are many, many more UserData fields available for account configuration that I'm not using;
  • the command object method does nothing outside of it's intended scope: it creates a user account, that's it.

Use it from PowerShell

Now that I have the command working, I want to see it working in PowerShell.  I'm taking a minimalist approach starting out.  Once I implement a few more commands and plug them into PowerShell, I'll see what implementation patterns emerge and replace this approach with something cleaner.  But for now, this mess will do:

[System.Reflection.Assembly]::LoadFrom( 'automation.commands.dll' ); 
function new-useraccount() 
{ 
    param( [string] name ); 
     
    $cmd = new-object automationcommands.createuseraccountcommand; 
    $cmd.Name = $name;
    $cmd.Execute(); 
}  
new-useraccount -name 'scott'; 

Hmmm ... runs silent, no output ... but looking at the system backend, I can see that it works.  

Use it from FitNesse

I downloaded the latest stable version of FitNesse from http://www.fitnesse.org/ and followed Cory Foy's short tutorial on using it against .NET assemblies (which is still accurate after 3+ years, #bonus) to get things running.  I created a new page and entered the following wikitext and table:

!contents -R2 -g -p -f -h 
!define COMMAND_PATTERN {%m %p} 
!define TEST_RUNNER {dotnet\FitServer.exe} 
!define PATH_SEPARATOR {;} 
!path dotnet\*.dll 
!path C:\dev\spikes\Automation\PokerRoom.Fixtures\bin\Debug\pokerroom.fixtures.dll  
A simple test of the CreateUser command: 
|!-PokerRoom.Fixtures.CreateUserAccount-!| 
|name|created?| 
|phil|true| 
|bob|true| 
|alice|true| 

I hacked up a quick fixture to support the table...

namespace PokerRoom.Fixtures 
{ 
    public class CreateUserAccount : fit.ColumnFixture 
    { 
        public string name { get; set; }  
        public bool created() 
        { 
            ICommand cmd = new CreateUserAccountCommand { Player = name };
    
            return cmd.Execute();
        } 
    } 
} 

... build it, and the FitNesse tests are green ...

After verifying that the users are actually created in the live system using our proprietary tools, I'm satisfied.

Moving Forward

So far so good.  It's very dirty, but it's working.  w00t * 2!

While developing this today I noted a few areas of concern:

  1. In the command object, there are several dependencies that obviously should to be injected.  Namely, the IUserService instance and the authority credentials;
  2. These dependencies are only really needed in the Execute() method;
  3. Looking ahead, I know I'm going to have many of these services, and it will be a pain to inject them all for each command instantiation;
  4. Compositing commands into complex behavior will eventually lead to the need to share state between commands.  I have an idea of how to manage this, but I'm concerned it will be cumbersome;
  5. There needs to be some kind of feedback when using the command from PowerShell; not sure where this should live or what it should look like at the moment...
  6. PowerShell will have a lot more to offer if I integrate with it more deeply.  I'll have to think about what this will look like, so as to minimize the amount of custom scripting necessary to run commands while accessing the full PowerShell feature set;
  7. I need to learn a lot more about FitNesse :).  I've already given the elevator speech to a coworker and demonstrated the fixture - he had a lot more questions than I had answers...

My next few posts will detail how I address these and other concerns.  Next post will detail some prefactoring to take care of items 1-4, maybe demonstrate command compositing.



Dependency Infection

§ June 17, 2008 07:27 by beefarino |

This post is about Dependency Injection frameworks.  It's not a survey, but you can find a good one here.

No, I'm afraid this is more of a rant.  You see, I'm a big fan of DI, and there's a pattern showing up in many of the frameworks that I don't care for: the frameworks want to infect my objects with dependencies in order to support the framework itself.  

In almost all cases the new requirements take the form of attributes on types, members, and parameters to "assist" the IoC container.  For example, if I choose Unity, I'm expected to pepper [Dependency] attributes on my object members.  If I use Ninject I need similar attributes to control activation behavior of my object.  Castle has a similar attribute serving the same purpose, but its use is optional.

I'm not picking on these frameworks specifically, they're just the examples that came to mind first.  A framework that forces me to use attributes like these leaves a bad taste in my mouth.  Why?  Because I don't think my objects should need to know anything about the framework managing their dependents and dependencies.  I see it as a Bad Thing™ for several reasons:

  1. The code behind my object must now manage its main purpose and how it will participate in the IoC container.  This violates the Single Responsibility principle I'm working so hard to uphold by using DI in the first place;
  2. Forcing my code to reference a specific DI library ties my object to that library.  If I end up using the object in another injection context (e.g., during unit tests, in another DI framework, or in a non-DI client), I have to drag the DI framework along for the ride.  This seems fishy when my goal is to decrease unnecessary coupling and isolate dependencies;
  3. Using attributes ties the DI context to the object's type definition, when the proper place for this context is the IoC container configuration.  For example, a type may be used as a singleton in one context, but as transient or pooled in another;
  4. These attributes don't appear to be necessary.  There are cleaner ways to communicate things like injection points, such as the CLR type model itself - e.g., public members and parameters are injectable, private members are not.

I want IoC to be a simple process of:

  1. Define types;
  2. Assemble them into a usable graph;
  3. There is nooooooooooooooooo step 3.

As I see it, the point of IoC is to get steps 1 and 2 to have as little to do with each other as possible.  When step 1 involves referencing the DI framework used in step 2 and decorating code, I hear a resounding "FAIL" in my head.

I've coined the phrase "dependency infection" to describe the proliferation of attributes and the addition of external dependencies mandated by some DI frameworks.  I plan to keep scoping out different IoC frameworks, but of late I keep coming back to Spring.NET and Castle and their complete acceptance of my bare naked and undecorated CLR objects.