-=//mawi.org//=-
 Wednesday, July 11, 2007

I introduced the factory facility of windsor (or actually castle microkernel) at the end of my previous project and I submitted some patches on it's programmatic use, and there is not so much documentation on it (well, not any on that part) so a little writeup was in order.

What is windsor? 

If you don't know what a container/IoC/DI is, and like to know concepts, check this out. If you don't know and want an example of windsor, check this out. A container is a little piece of frameworkish code that takes care of constructing your instances for you in a OO program, so you don't have to keep track of what goes where which simplifies alot.

 

You use it by first describing the classes you use and then asking for an instance of one. For example, you can tell it that you have a class D that uses an instance of class A and C. Class C in turn needs an instance of a class B. This is done in some init area of your code. Then in the program, you can say give me a D (resolve), and it will create A, create B and use it to create C and use these to create a D and return to you. Example classes:

 
public class A { }
public class B { }
public class C
{
   public C(B instanceOfB) { }
}
public class D
{
   public D(A instanceOfA, C instanceOfC) { }
}

 

Example use in test:

 

[Test]
public void MostBasicExample()
{
   IKernel container = new DefaultKernel();
   container.AddComponent("keyForClassA", typeof(A));
   container.AddComponent("keyForClassB", typeof(B));
   container.AddComponent("keyForClassC", typeof(C));
   container.AddComponent("keyForClassD", typeof(D));
 
   D anAInstance = 
      container.Resolve("keyForClassD", typeof(D)) as D;
 
   Assert.That(anAInstance, Is.TypeOf(typeof(D)));
}

 

Concepts/acronymns are "inversion of control" and "dependency injection", I like to refer to it as just a container, it's imprecise and contextual instead of sacrificing simplicity to get precise, but that's who I am. It's just oo, really. There are several such pieces of container code for .NET; castle windsor, spring.net and the objectbuilder framework from ms that is used in their application blocks, etc. I personally favor the castle project implementation because of it's ease of use and simplicity.

 

Use your own wrapper 

I feel the default container lacks some stuff, so I wrap it and add generics, methods that omit the key (sometimes I know that I will only have one implementation of a class in a system) and that look at metadata for attributes in an assembly and auto register. I make my wrapper a singleton. I slap on a custom attribute I call "ContainerComponent" on the example classes above and the test becomes:

 

[Test]
public void MostBasicExample()
{
   Container.Instance.AddFromAssemblyOf<A>();
   D anAInstance = Container.Instance.Resolve<D>();
 
   Assert.That(anAInstance, Is.TypeOf(typeof(D)));
}

(In fairness, there have been some recent commits that move toward this.)

 

The factory facility example 

Windsor can be extended via facilities, small pieces of code that add small pieces of functionality. The factory facility allows us to tell windsor to use a certain method (instance or static) on a class to create an instance of a class. I added some simple methods to add factories programmatically. Here are some example classes:

 
public interface IUserRepository
{
   void UpdateUser();
}
 
public class UserRepositoryImplementation : IUserRepository
{
   public void UpdateUser()
   {
 
   }
}
 
public class UserRepositoryFactory
{
   public UserRepositoryImplementation Create()
   {
      return new UserRepositoryImplementation();
   }
}

Factory support facility programmatically 

Here is an example test using microkernel and programmatically using the factory support facility (currently in trunk):

 

[Test]
public void FactoryResolveWithProposedFacilityPatch()
{
   IKernel kernel = new DefaultKernel();
   FactorySupportFacility facility = 
      new FactorySupportFacility();
   kernel.AddFacility("factory.support", facility);
 
   string userRepositoryKey = "userrepository";
   facility.AddFactory<IUserRepository, UserRepositoryFactory>
      (userRepositoryKey, "Create");
 
   IUserRepository userRepository = kernel.Resolve(
      userRepositoryKey,
      typeof(IUserRepository)) as IUserRepository;
 
   Assert.That(userRepository, 
      Is.TypeOf(typeof(UserRepositoryImplementation)));
}

 

I think that is messy, if we use a little container wrapper and say that we have don't need the key to differentiate

between implementations, it becomes:

 

[Test]
public void FactoryResolveWithContainer_NoKey()
{
   Container.Instance
      .AddFactory<IUserRepository, UserRepositoryFactory>
      ("Create");
 
   IUserRepository userRepository = 
      Container.Instance.Resolve<IUserRepository>();
 
   Assert.That(userRepository, 
      Is.TypeOf(typeof(UserRepositoryImplementation)));
}

 

Fuller example

Here are some example classes for a fuller example:

 

   public class FileStorageService
   {
 
   }
   public class AnnounceService
   {
      private FileStorageService _storage;
      private IUserRepository _userRepo;
 
      public IUserRepository UserRepo
      {
         get { return _userRepo; }
      }
 
 
      public AnnounceService( FileStorageService fileStorage,
         IUserRepository userRepo )
      {
         _storage = fileStorage;
         _userRepo = userRepo;
      }
 
   }

 

Example:

 

[Test]
public void FactoryResolveWithContainer_FullerExample()
{
   Container container = Container.Instance;
   container.AddFactory<IUserRepository, 
      UserRepositoryFactory>("Create");
   container.AddComponent<FileStorageService>();
   container.AddComponent<AnnounceService>();
 
   AnnounceService announceService = 
      container.Resolve<AnnounceService>();
 
   Assert.That(announceService.UserRepo, 
      Is.TypeOf(typeof(UserRepositoryImplementation)));
}

 

Parameters 

You can set parameters for the factory method at configuration time and at runtime. Will continue with that and post code later on, stay tuned.

.NET | Code
7/11/2007 5:35:41 PM (Romance Daylight Time, UTC+02:00)  #    Comments [1]  |  Trackback
 Monday, June 25, 2007

At the last meeting of our monthly agile get togethers (which was really nice) we talked about a bunch of things; one being how to help teams keep using techniques that are helpful and reflect on what they do so that they may find new helpful techniques.

 

At my current short assignment I am helping a team with their process and their work and we have been talking about these things, so the discussion was very useful to me. The reward of task completion and (if you have a quick feedback cycle via some receiving customer standing by) delivery is huge and it can be hard to provide an alternative mechanism that rewards refactoring and design investments.

 

One type of tool I find useful to get a grip on group dynamics are the personality catalogs a'la DISC. There is a correlation between the personality types of such models and preferred rewards, "Drivers" are more focused on task completion and delivery, for example. However, the model notes a tendency or potential factor, it is not static - the challenge is to affect this focus in a beneficial direction, usually so that more design effort is undertaken.

 

There is little point in enforcing policies by means of negative reinforcement. At AgileOresund we discussed how to stimulate a feeling of professionalism / "professional pride" so that there will be more care taken in how things are accomplished than just that they are accomplished.

 

I feel that this can be approached via a general belief and support of the individual, and a stimulation of his/her personal goals. These goals are often in line with the goals of the organization, and create a much greater drive. A dialogue aimed at this is often neglected in companies today: Many companies I've been to lack leaders who have the ability to create a solid and effective conversation of this type. In contrast, the "actual" leaders (may be team leads or just in terms of the socially context, due to age and experience) are sometimes not interested and/or do not have time and do not prioritize this important conversation. I feel that this is a loss for everyone - the companies, the industry as a whole and the individuals.

 

Another perspective on this discussion is the model of developers that microsoft uses, and there has just recently been some controversy around how it was recently expressed at a blog. Microsoft uses a set of persona that represent different developers. In a recent post - an discussion of code production and tools - quality and needs were presented based on one of the persona, Mort. Mort is the least technically interested developer, that merely wants to get the job done, and the code he produces does not fit in a complex codebase that will need to be maintained over a long period of time, and so on, it is posited. There follows (and it is still active) a heated and fairly interesting discussion, where people mostly disagree with how the original poster related Mort and his view of the world to agile practices.  Regardless, using these persona as an analysis tool in this way feels clumsy to me, I don't think that it is what they were intended for. 

 

Yet it does send a thought to my rewards analysis: If we accept the persona model as useful, and think about the Mort persona in a typical scenario, I think that Morts in general will be aware that they are not the "alpha geeks". Morts may feel a sense of distance and lack of engagement due to this. Thus, they pursue other types of rewards and recognition, which may be task completion. If so, it seems logical that they value it over investing effort in design, and other technical aspects of the work, that do not contribute "directly" to creating the functionality in a visible way. They may feel that they cannot gain recognition for creating the best design for the tasks, but they can complete the tasks quickly.

 

Naturally, creating an open and positive work environment is of course necessary.

 

  Again, in order to counter this is (in addition to pursuing and maintaining humility and openness at all costs, as has been recommended forever) I believe in working with the individual and pushing them to create a vision for themselves, get aware of their ambitions and formulate a direction of where they want to go. Most often, that will be in line with where the organization wants to go. I believe very much in the drive and the passion that we all have, if awakened, if nourished -  all it takes is someone to believe in it.

6/25/2007 12:24:32 PM (Romance Daylight Time, UTC+02:00)  #    Comments [2]  |  Trackback
 Monday, May 21, 2007

This week was short work-wise, and went by quickly. Last week was hectic and long. Me and my colleague Truls gave a seminar on NHibernate, a little ActiveRecord and some of the new MS OR stuff. Then I spent three days with another consulting company, showing them the ins and outs of NHibernate and sprinkling just a little WCF on the last day. In so doing, I caught myself serving out some code that I have used. Normally, I don't dish out any code here, but this might be useful to some:

 

It's a small WCF test helper that I have used to do explorative testing of WCF and even more so for integrative smoke tests of WCF services.

 

There is a zip attached that contains one vs.net 2005 project with a WCF hello world and one nunit test that runs that service. That test is an integration test, it cranks up the whole WCF machinery. Most of my WCF integration tests (all, in fact) do not test any concurrency issues. They are more simple smoke tests that everything seems to work as expected. What I usually want is to test the machinery but have one instance invoked, so that I can execute some assertions on the results using that instance afterwards.

 

Usually, you will not implement your WCF service as a singleton (although it is one of the instancing modes), for one of several reasons - scalability for example. Using the other instancing modes means that you (by default) do not control construction of your the instance that gets to serve the requests, and thus in a test situation, we do not have a reference to the instance used by WCF. One way around this is to create a custom instance provider. The instance provider in WCF (class implementing IInstanceProvider, the default being a private class in InstanceBehavior, reflect it) is responsible for supplying new service instances. I won't talk about it here, suffice it to say that my SingletonInstanceProvider simply returns one (settable) instance each time, thus making the service a singleton. It is a service behavior that we add to the servicehost description.

 

Why do this? Simply so that I can implement my service using an instancing mode that I want, but still run simple smoke tests on it. It is one solution, there are doubtless many others, if you have a better one, please give me a shout.

 

So, the testhelper or testharness that is enclosed actually does a couple of things. I won't talk about them in detail, this is roughly it:

 

  • Provide a simple way to create and start a service host and get a client to run tests against it.
  • Provide a way for tests to share services, so that the WCF machinery does not need to be restarted.
  • Get the services set up using the SingletonInstanceProvider easily
  • Allow test to access host before it is started to modify/further configure
    ( this is why you see castle in there, the client (a dynamic proxy wrapper) is actually a proxy that opens the service late/JIT )

You use it like so:

 

IMessageOfTheDay client1 = GetClient
   .For<IMessageOfTheDay>()
   .Using(new NetTcpBinding())
   .Running(serviceInstance);

 

This sets up a service host for the IMessageOfTheDay service contract, using the netTcpBinding (optional, default is named pipes since it is the fastest) and running the instance supplied. See the demotest.

 

Comments welcome. Btw, this uses my singleton implementation, I'll make a note of that tomorrow, but it's simple.

 

Questions: Has anyone seen another wcf test harness like this? I usually do all my network integration testing using some thread harness with synchronization between, and did my WCF testing in a similar (not the same) way. This harness simplified things quite a bit.

 

BTW: Most of the code is in one file; TestHelper.cs. It's a bit unwieldly, sorry, but easier to copy - you still need the singleton.cs though. I may update later if I get time.

 

Again, the download is here.

5/21/2007 2:00:04 AM (Romance Daylight Time, UTC+02:00)  #    Comments [0]  |  Trackback
 Wednesday, May 02, 2007
I almost forgot to post about this; next week holds a seminar on NHibernate, Castle and MS coming offerings of EF. I will be talking about NHibernate and castle activerecord and my colleague Truls will talk about MS Entity Framework. It's an overview, which we hope will give developers looking to use OR mappers a bit of background, to aid their decision making. We call it "Data access showdown"! Do stop by!

5/2/2007 9:33:41 PM (Romance Daylight Time, UTC+02:00)  #    Comments [2]  |  Trackback
 Sunday, April 29, 2007
(or rather respect and stimulating work...)

While we were in Dijon testing our new system I read most of the last IEEE Computer issue - which I often do not, but reading magazines filled out the cab rides. In it you find this article. Nicholas Carr blogged and a pretty nice discussion followed. I certainly disagree with the conclusion Nick comes up with, and I think that the article is more nuanced but many statements are made without proper underpinning. Regardless, the discussion inspired this pretty funny cartoon, too. One commenter (Tony Healy) drew the parallell to geeks great nerd needs: I think that the need for respect and the awesome feeling of being able to help others is magnified in most geeks. Some thrive on the "I am smart" feeling. Like most, I have transformed mine into, "see, you can do it this way!", after which I often get a "oh, great, thanks!", which gives me a warm, fuzzy feeling inside.

That - and feelings like it - are what I live for. Sure, this can be taken advantage of, and is taken advantage of, I'm sure. But, at the end of the day, as long as I keep getting what I live for... it's pretty much ok. Soon, I will cultivate the business person in me, or something... Right now, I gotta go on doing some demos this lovely sunday afternoon.

4/29/2007 4:37:57 PM (Romance Daylight Time, UTC+02:00)  #    Comments [0]  |  Trackback