MS.NET Generics - how lame !

May 14th, 2008

I was fairly excited about taking advantage of generics in my current C# project.  It was going to save me a fair bit of time, and prevent the proliferation of boiler-plate cut and paste code.  My requirement was fairly common, I was writting a message handler which had to work with several versions of message.  Each message version was fully described by XML in the form of an .xsd.  Each message version was a distinct class - so version 2 did not derive from version 1.  Using the Dot.Net tool xsd.exe I was able to generate some nice wrapper classes for easy serialization and member access of the differing message versions.  So far so good, I thought.

Then I started writting my message handler.  Since I wanted to accomodate any message version, I instinctually felt that Dot.Net generics was the means to coding nirvana.  I have extensive experience with C++ templates, and felt that this would stand me in good stead.  I jumped in, only to discover that Dot.Net generics are only waist deep (when compared to C++ templates) - good thing I didn’t jump in head first.

Let me explain.

Imagine you have a set of classes that you DIDN’T author, but you know they are all very similar.  You’d like to work with them in a similar manner.  Let’s say they look like this:

class SomeTypeA
{
    public void Func()
    {
        Console.WriteLine("Hello London");
    }
}

class SomeTypeB
{
    public void Func()
    {
        Console.WriteLine("Hello New York");
    }
}

Now you want to make a function which can work with any of those types

static void Test<T_type>(T_type some_type)
{
      some_type.Func();
}

Ooooops !

You can’t do that because Dot.Net hasn’t implemented generics in a manner that is anything similar to template types in C++

You see, in C++ the compiler would wait until you tried to call Test<>() with a particular type, then it would check that that type had a function which matched the name and parameter list for Func(). If it did, it would allow this syntax; but, in C# — Even though it is interpreted and has reflection - the compiler borks.

If you wanted to do something similar, you’d have to use a contraint on the generic function, and the contraint would have to indicate that the T_type implemented a particular interface with a function ‘Func’. Since you aren’t the author of SomeTypeA or SomeTypeB you can’t do anything generic with them, even though you know they both implement the same function ‘Func’.

Of course, you could derive types from them which implemented an interface and simply passed through to the base SomeTypeA or SomeTypeB, but now you have a explosion in types. You’d have -as a minimum- a new interface type, and a new derived type for every unauthored type you wanted to treat generically. so for a very basic project like ours, we’d need 3 new types (an interface and two wrappers) just to use the two existing types generically. Now imagine what happens when different versions support subsets of functionality and the whole thing gets extremely messy very quickly.

All in all Dot.Net generics seems like a half solution. They actually make the developers job more tedious rather than less. Oh well, I guess I shouldn’t be surprised, Dot.Net is like much of what has come out of Microsoft recently, very shiny on the outside, but full of wholes on the inside.

FYI, here’s the equivalent C++ template code, which works just fine with the two types without having to decorate the template function with idiotic information about what interface to use, or necessitating the implementation of an interface and wrapper classes

class SomeTypeA
{
   public:
   void Func()
   {
     cout << "Hello World" << endl;
   }
};

class SomeTypeB
{
   public:
   void Func()
   {
     cout << "Goodbye World" << endl ;
   }
};

template<class T_type> void Test(T_type& some_obj)
{
    some_obj.Func();
}

int _tmain(int argc, _TCHAR* argv[])
{
    SomeTypeA a;
    SomeTypeB b;
    Test(a);
    Test(b);
}

Nice -

GridControlView and data binding borken-ness

April 30th, 2008

Be warned - attempting to use MS.NET DataGridView and binding to a DataTable (instead of a DataSet - which wraps a table)  has been know to cause heart-ache.

SourceSafe command line (ss.exe) woes

April 2nd, 2008

I have a simple issue with MS SourceSafe - I want to uncheckout files which are unchanged. 

If I restrict myself to the GUI (SourceSafe Explorer) and try to find all the files that are in same in both locations, I get a list of files that includes files that I haven’t yet checked out.  Conversely I am allowed to find all the files that I have checked out, but that includes files with changes in them. 

So, I clearly need something a bit more sophisticated than the GUI.  At this point I decde to go to the command line application (ss.exe) to see if I can’t work a way to automatically determine checked out files that are unchanged, and uncheckout those files.

My guess is that Microsoft doesn’t use ss.exe, because, frankly, it sucks.  The documentation is very poor, and the command syntax is error prone due to the bizarre mixture of ‘options’ and ‘commands’.  Activities which one would think are totally unnecessary (such as setting the current repository -Database in MS parlance-, when the current directory is a repository image -i.e. a source tree checked out from SourceSafe) are mysteriously dependant upon environment variables, which can’t be over-ridden from the commandline (at least I can’t get it to work)

I’m not a MS basher - really- although recently it’s becoming difficult to not bash most of their stuff.

The curious case of InstallUtil and service parameters

March 18th, 2008

Microsoft .Net has provided a few classes which are supposedly to help you more easily to install your service (or presumably, any assembly) by way of InstallUtil.exe You add these classes to your service project by right clicking on your service designer view and selecting ‘Add Installer’. You can set a very few parameters within the properties of the added classes, but unfortunately, there is a twist.

There seems to be a major problem with InstallUtil. It is supposed to forward command line arguments to your service installer classes, especially the supposedly inherently supported ‘username’ and ‘password’ parameters. You will very likely want to use these parameters if your service is going to run as any form of priviledged account, and you wish to be able to install the service from the commandline.

In a nutshell, InstallUtils doesn’t seem to pass any parameters other than: logtoconsole, assemblypath, logfile to the ProjectInstaller classes. Of course, this is particularly unhelpful if you are trying to pass username and password or any service specific options or registry entries to your service install routines using on the commandline.
To prove this you could easily add the following code snippet to you over-ridden Install method
— Proof —-

Console.WriteLine(”SUPPLIED Context parameters:”);
foreach (DictionaryEntry de in this.Context.Parameters)
{
Console.WriteLine(”Key[{0}], Value[{1}]“, de.Key, de.Value);
}

Example: installutil myservice.exe /username=dummy /password=dummy
gives this

SUPPLIED Context parameters:
Key[logtoconsole], Value[]
Key[assemblypath], Value[D:\Source\Testing\myservice\myservice\obj\Debug\myservice.exe]
Key[logfile], Value[D:\Source\Testing\myservice\myservice\obj\Debug\myservice.InstallLog]

You can see that NOT only weren’t your parameters passed in , but some default parameters (over which you seem to have no control, were. How nice !

Luckily the solution to this issue is relatively easy to accommodate

To put things right, in a relatively generic manner we construct our own temporary InstallContext (because it parses options *almost* nicely) then make sure we don’t stomp on anything that InstallUtil has provided before adding any missing parameters to the passed in Context.

We ARBITRARILY define any† parameter with no value to be invalid this happens when InstallContext constructor parses the raw command line and parses both InstallUtil (param[0]) and the service assembly name as keys with null values

† NOTE: there is special case handling for empty passwords (empty passwords are a stupid idea, but let’s not go there) We do allow for empty passwords, which are differentiated from null by way of the empty string (”"), So, on the commandline this would be: installutil myservice.exe /username=dummy /password=”"

Also, please note that the username IS NOT processed, so you will probably need to provide the domain. For those of you who are wondering, the local machine domain is signified by a ‘.’ character, so the syntax would be: installutil myservice.exe /username=.\dummy /password=”" or for a real domain: installutil myservice.exe /username=some_domain\dummy /password=some_real_password

Final note - aside from the special case of *no password* - no quotes are required unless the parameter value in question contains a whitespace character. This is the standard command line parsing rule, so should not pose a problem.

In in all this is shockingly poor stuff from MicroSoft - but, at least we’re used to that !

protected override void OnBeforeInstall( IDictionarysavedState)
{
String[] args = System.Environment.GetCommandLineArgs();
String no_log_file = null;
InstallContext tmp_ctx = new InstallContext(no_log_file, args);

foreach( DictionaryEntry de in tmp_ctx.Parameters)
{
// don’t process empty Values, except for password
if( !de.Key.ToString().Equals( “password”) &&
( null == de.Value || string.Empty == de.Value.ToString()) )
continue;
else
{
// don’t stomp
if( !this.Context.Parameters.ContainsKey(de.Key.ToString()) )
this.Context.Parameters[de.Key.ToString()] = de.Value.ToString();
}
}

base.OnBeforeInstall(savedState);
}

I apologize for the poorly formatted code, I can’t seem to understand how to get WordPress to make it look pretty.

A fixed size stack in STL

October 17th, 2007

Let’s assume you want to store the ‘last 5′ instances (values) of something.

You can do this pretty easily by subclassing std::dequeue, as follows:

#include <iostream>
#include <deque>
#include <algorithm>

template< typename T >
class fixed_stack : public std::deque< T >
{

public:
  fixed_stack( size_t ms ) : std::deque< T >(), max_size( ms ) {}

  void push_front( const T & v )
  {
  if ( std::deque< T >::size() == max_size )
      std::deque< T >::pop_back();

  std::deque< T >::push_front( v );
  }

  template< typename Tt >
  friend std::ostream & operator<<( std::ostream & os, const fixed_stack< Tt > & fs );

private:
  size_t max_size;
};

template< typename Tt >
std::ostream & operator<<( std::ostream & os, const fixed_stack< Tt > & fs )
{
 for( typename fixed_stack< Tt >::const_iterator it = fs.begin() ; it != fs.end() ; ++it )
  os << *it << ” “;
  return os;
}

int main( int c, char *v[] )
{
  fixed_stack< int > fs( 5 );

  fs.push_front( 1 );
  fs.push_front( 2 );
  fs.push_front( 3 );
  fs.push_front( 4 );
  fs.push_front( 5 );
  fs.push_front( 6 );
  fs.push_front( 7 );

  std::cout << fs << std::endl;
}