Thursday, March 04, 2010

Trouble with Team System workspace in VS2005

.. but I solved it

I have been developing in Visual Studio 2008 lately and the chances are reasonable that I will move to Visual Studio 2010 soon. However, in my current project I needed to create a SSIS thingy to do some clever data import. Since the database we are using is SQL Server 2005 I had to do a step down to Visual Studio 2005. Not a big problem since it's still installed on my machine.

Team System

Small problem was that we are using Team System for souce code control and work item management. That's a no brainer. Just download and install the Team Explorer for Visual Studio 2005.

Well easily done and away we go.

Login into the server and away we go!

Just a quick plug here. I am using an online hosted version of Team Foundation Server. It's provided by Online-TFS and works like a breeze. In a recent outsourcing job I had to work with a TFS instance hosted on the same internal network and that wasn't anywhere close in performance as this online version!

It may seem pricy at first, but I can access it from anywhere on the Internet and still have great performance.

After starting VS2005 I just had to logon and away I went. I quickly had the Team Explorer on screen and then I just wanted to hook up to the correct Workspace to start uploading the first version of SSIS project.

That's when things went a bit wrong. I had no options in the Source Control Explorer window. I could browse to the folders on TFS but couldn't add or get anything.

I was a bit stumped.

So I did search and found some stuff on MSDN about the File - Source Control menu. But that only showed Visual SourceSafe. Ugh!

I looked a little further and decided to go through the Options dialog where a lot of the hidden gems can be found.

The solution

Going through the good old Tools - Options menu I brought up the Options dialog. And there it was hiding under the Source Control item.

I just had to pick the right plugin from the box to get going.

While there I had a quick look at the other options to see if they suited me way of life and then clicked OK.

That's it

So then I could get cracking with the mysterious ForEach Loop Container.

Reblog this post [with Zemanta]

Friday, January 22, 2010

Porting a framework to Silverlight

.. a journey getting to the contents

The last time I have been getting familiar with Silverlight. As a .NET developer with a big focus on the web I am interested in the possibilities of this plugin. (Eventhough, I also keep a close eye on the interesting stuff around HTML5.)

The Microsoft Silverlight stack, vectorization...Image via Wikipedia

I always wanted to add a little more to web applications and sites that are maybe possible using clever Javascript, but are probably easier to achieve using a plugin like Flash. Being quite fluent in .NET and C# and reasonably agile in Javascript I didn't want to learn yet another language and different IDE. So, when Silverlight came on stage I was immediatelly interested. I could be using the familiar Visual Studio, familiar C#, familiar (though slightly limited implementation of) .NET framework to do some exciting new stuff. XAML came in as a new aspect, but that was already part of the WPF stuff, so not completely new. Expression Blend to create all sorts of horrible interfaces and well, the sky is not even the limit anymore.

After some useless experimentation (extending "Hello world!") I decided to stop right there and drop everything and make a good start right from the beginning. Fundamentals first.

A framework

Within our company we use a clever framework that implements the MVC pattern. We use the same framework for Windows Forms application and ASP.NET applications. By completely separating the View logic from the Model and Controller (as it should be done) we can use the same Model and Controller logic in both types of applications.

The framework has a Mediator and all functionality is handled through that using Commands. All View controls are registered with the Mediator and are signalled to update the view when "things" change in the Model. The controls then update themselves and show or hide bits of themselves.

At first there was a bit of getting used to this way of programming, but now it strikes me again and again how little code is needed to implement logic.

All logic is handled in commands. When a button is clicked the Mediator is called to execute a command with some optional parameters. These Commands are implemented in various classes and are decorated with a Command attribute and implement an ICommand interface. The ICommand interface makes that the methods that a Command needs are implemented. The Command also has access the Model through ApplicationData object. I made a SilverlightApplicationData type with some small changes to the WebApplicationData type. For instance in the WebApplicationData we grab the buildnumber from the Web.Config and there is no such thing in Silverlight, so it is dropped for this first implementation.

Anyway, just add the attribute and we are good to go.

[Command("COMMANDNAME")]

The code the ICommand interface has among others a Do() method that can be called by the Mediator. A typical Button Click EventHandler is really simple.

Mediator.Execute("COMMANDNAME", "string parameter");

Or ..

Mediator.Execute("COMMANDNAME", "string parameter", intParameter, someOtherClassParameter);

Every parameter after the command name is passed to the actual Command as argument for its constructor.

The Mediator then executes the Command. However, the framework doesn't know which Commands will be implemented. Neither do I. What is needed is a Dictionary with all available Commands.

Dictionary<string, Command> commands

How to can the framework know which commands there are? Do we need to maintain a list in a config file? A bit nasty really. But the backbone of .NET Framework comes to the rescue: Relfection.

Reflection

Using reflection we can iterate all application assemblies and scan all types and make a Dictionary with all types that have the Command attribute. These can then be stored in the Dictionary.

Sounds easy, but is it?

Windows and web is simple

For Windows and Web applications iterating the assemblies is quite simple. We just look at the content of the Bin folder and load all *.dll (and *.exe) files. Then using reflection we scan all Types for the Command attribute. When found we add them to the Dictionary.

            foreach (string file in Directory.GetFiles( path, searchPattern, SearchOption.AllDirectories ))
            {
                Assembly assembly = Assembly.LoadFrom( file );
                Type[] types = assembly.GetTypes();
                foreach (Type type in types)
                {
                    object[] attr = type.GetCustomAttributes(typeof(CommandAttribute), false);
                    if (attr.Length == 1)
                    {
                        CommandAttribute attribute = (CommandAttribute)attr[0];
                        Command command = (Command)assembly.CreateInstance( type.FullName );
                        commands.Add( attribute.CommandName, command );
                    }
                }
            }

This is all done in a static CommandManager so we only need to scan the files once.

Silverlight is slightly different

With Silverlight the situation is a bit more complicated. There is no Bin folder that can be scanned. There is a ClientBin folder, but that's on the web server and even then the files are inside the Xap file!

Inside that renamed Zip file we find the assemblies and AppManifest.xaml file in which these files are listed. Well how do we get there?

Doing quite a bit of Googling I finally got on the right track. The above code sample needs quite a bit of rework. Whe need to do a number things:

  1. Open the Xap file
  2. Read the AppManifest.xaml.
  3. Parse the names of the assemblies
  4. Load the assemblies from the Xap file

Eventhough the Silverlight application is downloaded by the browser to the client computer we can not really get at the Xap file directly. That's the sandboxing security model working against us. So we need a clever workaround.

Luckily there is a way to get there. We can download the file to Local Storage. Since we are on the web this happens asynchronously. Using the OpenReadCompletedEventHandler we can continue the process.

Note that we also check for the existence of the Xap file in LocalStorage, just to prevent repeated downloads when you refresh the web page.

         Uri xapUri = Application.Current.Host.Source;
         string[] parts = xapUri.AbsolutePath.Split('/');
         xapFile = parts[parts.Length - 1];  // the filename is the last part of the path

         using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
         {
            // check if the file is available
            if (!store.FileExists(xapFile))
            {
               // when not available download it
               WebClient webClient = new WebClient();
               webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(WebClientOpenReadCompleted);
               webClient.OpenReadAsync(new Uri(xapFile, UriKind.Relative));
            }
            else
            {
               LoadAssembliesFromIsolatedStorage();
            }
         }

When WebClient has completed download the stream is copied to IsolatedStorage

      private static void WebClientOpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
      {
         using (IsolatedStorageFile storageFile = IsolatedStorageFile.GetUserStoreForApplication())
         {
            IsolatedStorageFileStream fileStream = storageFile.CreateFile(xapFile);
            WriteStream(e.Result, fileStream);
            fileStream.Close();
         }
         LoadAssembliesFromIsolatedStorage();
      }

Now the assembly processing can begin.

      private static void LoadAssembliesFromIsolatedStorage()
      {
         using (IsolatedStorageFile storageFile = IsolatedStorageFile.GetUserStoreForApplication())
         {
            IsolatedStorageFileStream fileStream = storageFile.OpenFile(xapFile, FileMode.Open, FileAccess.Read);

            // parse the AppManifest.xaml file
            Stream manifestStream = Application.GetResourceStream(new StreamResourceInfo(fileStream, "application/binary"), new Uri("AppManifest.xaml", UriKind.Relative)).Stream;
            string appManifest = new StreamReader(manifestStream).ReadToEnd();

            XElement deploymentRoot = XDocument.Parse(appManifest).Root;
            List deploymentParts = (from assemblyParts in deploymentRoot.Elements().Elements()
                                              select assemblyParts).ToList();

            // now load assemblies one by one
            foreach (XElement xElement in deploymentParts)
            {
               string source = xElement.Attribute("Source").Value;
               AssemblyPart asmPart = new AssemblyPart();
               fileStream = storageFile.OpenFile(xapFile, FileMode.Open, FileAccess.Read);
               StreamResourceInfo streamInfo = Application.GetResourceStream(new StreamResourceInfo(fileStream, "application/binary"), new Uri(source, UriKind.Relative));

               Assembly assembly = asmPart.Load(streamInfo.Stream);
               // from here the code is unchanged
               Type[] types = assembly.GetTypes();
               foreach (Type type in types)
               {
                  object[] attr = type.GetCustomAttributes(typeof(CommandAttribute), false);
                  if (attr.Length == 1)
                  {
                     CommandAttribute attribute = (CommandAttribute)attr[0];
                     Command command = (Command)assembly.CreateInstance(type.FullName);
                     commands.Add(attribute.CommandName, command);
                  }
               }
            }
         }
      }

Well, it took quite some googling around and advice from a friend to get this working, but in the end the steps are quite easy to understand.

Almost there ..

So now we have everything we need. Almost that is.

As I mentioned earlier Silverlight has a slightly limited implementation of .NET framework in the sense that not all namespaces are completely implemented in the same way. And that threw up another hurdle to take.

To create an instance of Command we use an overload of the CreateInstance method in which we can pass the parameters for the command in the args parameter.

ICommand command = (ICommand)assembly.CreateInstance( commandType.FullName, false, BindingFlags.Default, null, args, CultureInfo.InvariantCulture, null );

Unfortunately Silverlight does not have this overload. We cannot pass any parameters to the instance using CreateInstance. In effect only the default constructor is called. Why the overload is omitted in Silverlight strikes me as odd.

Yet, more research was needed to solve this problem. More Reflection was needed to find the correct constructor for the type.

         Type[] parameterTypes = new Type[args.Length];
         // Initialize a ParameterModifier with the number of parameterTypes.
         ParameterModifier parameterModifiers = new ParameterModifier(args.Length);

         for (int i = 0; i < args.Length; i++)
         {
            parameterTypes[i] = args[i].GetType();
            parameterModifiers[i] = true;
         }

         // The ParameterModifier must be passed as the single element of an array.
         ParameterModifier[] paramMods = { parameterModifiers };

         // Get the constructor that takes an integer as a parameter.
         ConstructorInfo constructorInfo = commandType.GetConstructor(BindingFlags.Instance | BindingFlags.Public, 
                                       Type.DefaultBinder, parameterTypes, paramMods);
         ICommand command = (ICommand)constructorInfo.Invoke(args);

This made it all work.

Mediator.Execute("COMMANDNAME", "string parameter");

The Mediator can now make a deep copy of the Command referenced by the name "COMMANDNAME" (using the constructor that takes string parameter) and then call that Command's Do() method to actually execute it.

A really interesting journey it was and now I can start to make something useful using this framework.

Reblog this post [with Zemanta]

Friday, December 04, 2009

Top one reason projects fail

.. it's not about a person, but about the process

This morning I came across an article by Amit Sarkar "Top Ten Reasons Why A Project Fails And What You Can Do To Change" and it triggered me to write a long comment to that. I don't know if anyone will ever read it as nothing appeared on the site. Might need moderation. Still I copied what I had typed into the box to reproduce it here. And the added some more text here and there.

First I suggest to hop over read the article.

My comment

Having been involved in quite a number of projects myself I think that I can honestly say that you are clearly a project manager that works according to the book. The problem is that the book is not correct. Or it might be the not the correct book. The Bible is not the best source of knowledge for project managers, nor is the Koran. Nor Harry Potter.

Genral objections

I will not break down all your 10 points.

But the biggest mistake in managing IT projects is the misconception that everything can be known at the beginning of a project. Requirements are never completely clear and will change during the project because of changing insights and demands from other systems.

Same goes for risks. Some can be identified ahead, but most risks are only becoming clear when the projects moves ahead and bumps into related systems that have limited possibilities.

It all sounds too familiar

Waterfall ModelImage via Wikipedia

The solutions you propose are related to the 'good old' waterfall model and that is no longer a best practice in IT world, if it ever was. Nowadays we would like to work in iterations taking small steps to make things work a bit and have close commitment from all team members and the project owner, the stakeholder or at least someone who can and will take decisions and who is a member of the project team as well. That way progress can be made in short cycles and the stakeholder is always involved and knows every step of the way.

Typically in such a process it is not known what comes out at the end. You might think beforehand that you need a better mobile phone and end up with something like Twitter.

Then ... what

IMHO a project manager is a facilitator for the project team. The project manager makes it possible for the team to do their work. At best he goes around serving coffee.

I have seen project managers who spend a lot of time in endless meetings with all kinds of layers of management and keeping all kinds of lists, but were never around when you really needed them. I pity them for the time wasted and myself for the time waiting for them to come back from the trenches.

I think that the points you mention are known problems, but the solutions you mention are not the way to go. In IT so many times the stakeholder has no real knowledge of IT in general and has no real idea about what it really is that he needs or wants.

To me it is important that a project team together with the stakeholder iterate over the product that will be delivered. Not everything will be known at the start (and that's okay), but that also means that you can't really plan anything ahead. It's impossible to have all requirements and all risks assesed and have solutions for these as well.

A final great to Amit Sarkar:

Good luck.

I love it when a plan comes togetherImage by Phillie Casablanca via Flickr

Conclusion

I know, I know, I am all wrong. I am not a project manager. Happy for that in a way. But I have been involved in a lot of projects that failed not because of bad team members or project managers, but because of the process that was chosen to do the project. Not as much the project management methodology (Prince or Cadence or whatever) but the process that was used to get from the start (nothing) to the end (something that all involved people can live with).

I think project management has come a long way (to the moon and back) and that in IT projects people need to understand that we do not know at the start of a project to which moon we are going and whether we are going any further than the coffee shop around the corner. Most of the time it is not rocket science.

So once again: Good luck.

Reblog this post [with Zemanta]

Tuesday, November 10, 2009

Streetview spreads fast

.. but is slow rolling out

Today I jumped up in joy as I could see some house where I used to live in The Netherlands on Google Streetview. I saw the Pier at Holwerd and the house of my sister. All great.

But the house where I live is not there (yet)

Uhm?

Somehow there seem to be some large squares of Streetview missing from the maps. Must be some data issue, I guess. Maybe some more files need to be synced between servers or what.

But why just my area that is missing? Have to wait I guess.

Means more wear and tear for my F5 key.

Looking beyond

Looking a bit beyond the borders of my small nation I see even more interesting things.

  • The coverage in Spain is quite extensive and probably on the same level as in The Netherlands. (Once these holes get plugged.)
  • Switzerland had some fuss about faces that were still recognizable, but still has some fair amount of Streetview.
  • The United Kingdom has Streetview splattered here and there over the map.
  • The coverage of France seems to be mainly limited to the Tour de France route that was covered last year.
  • Scandinavia is too ... cold? or reluctant? for Streetview
  • Italy has the same type of coverage as the United Kingdom
  • And the Czech Republic is the only country in Eastern Europe with Streetview
Looking even further beyond

Outside Europe only the The United States in Northern America and Australia, New Zealand and Japan have Streetview presence.

There are still a lot of miles to travel for the Streetview cars and tricycles.

I just wonder if it wouldn't be possible to somehow let the crowd fill the cloud? When enough people take enough pictures that are geolocated accurately enough than that could accumulate to a nice extra input for Google Streetview.

Wednesday, November 04, 2009

Perfect Pitch

.. for the sake of democracy

Visit this link:
http://adactio.com/journal/1623/

Helping Adactio get that perfect pitch. To nail it, even. You should probably link to his page too, if you’re so inclined to fight DMCA take-downs for the sake of SEO.

uhm

Well, when you have read the article then I do encourage you to create your own link to
http://adactio.com/journal/1623/