Tuesday, January 13, 2009

Really weird C# code

My ServiceLocator (which has been further updated since my last post on it, so on the off chance that anybody wants the latest version, leave me a comment) can only register functions with no parameters - Func. What happens if one wants to register a function with one or more parameters?

As an example, let's say that I have many possible connection strings, and in some cases when I want an instance of DataContext I have to initialize it with one of those. Since my ServiceLocator doesn't accept functions with parameters, I cannot write

  1. var dc = ServiceLocator.GetInstanceOf<DataContext>(connectionString); 


Here's a way of transforming a function with parameters to one without: create a function that returns the original function. That is, given

  1. Func<T1, T> f; 


I need another function that will return f:

  1. Func<Func<T1, T>> g = () => (a) => f(a);   


So, in order to register my DataContext I am now going to use the following syntax:

  1. Bind<Func<string, DataContext>>.To(() => (connectionString => new DBDataContext(connectionString))); 


and to retrieve the instance and initialize it correctly, I must use:

  1. var dc = ServiceLocator.GetInstanceOf<Func<string, DataContext>>()(connectionString); 


Not extremely clear, so some helper functions (and confining in a library of sorts) are probably needed.

Edit: I just made a change to the ServiceLocator code; one can now write:

  1. var dc = ServiceLocator.GetInstanceOf<string, DataContext>("connectionString");  


This is the overload for one argument:

  1. public static T GetInstanceOf<T1, T>(T1 arg1) where T : class  
  2. {  
  3.   return GetInstanceOf<Func<T1, T>>()(arg1);  
  4. }  


I only have 3 overloads (up to Func) but that should be enough for anything I might need in the foreseeable future. Oh, and I can still have / use the initial binding too (the one with no connection string). Cool :)

0 comments: