Tuesday, March 30, 2010

Zombies?

.. I ain't not afraid of no ghosts

While happily coding about the other day I hit Shift-F5 in Visual Studio and was greeted by the following dialog box:

Uh?

Get the gun and blow their brains out!

Well, I didn't. Just clicking the button made it go away. But I am on full alert now. But maybe I should visit this guy ...

LONDON, ENGLAND - JANUARY 11:  Canon David Par...Image by Getty Images via Daylife

Reblog this post [with Zemanta]

Thursday, March 18, 2010

Writing this HTML5 vs Silverlight post

... vice versa could be easy

I think that the writer is on a wrong track here as he is comparing two completely different things.

A new and fast rising standard for HTML and a browser plugin. The first being implemented across multiple platforms in rapid pace. The second being upgraded every 9 months and available on not all platforms.

Mind you I think both of these have huge possibilities and can do things that the others may not yet can do. I think they both have their unique use cases, but in most cases they have much overlap in possibilities.

Which one to choose depends on the situation and the market one is aiming for.

The article could have been a lot more subtle and a lot more realistic.

Refers to: http://www.silverlighthack.com/post/2010/02/08/Top-Reasons-why-HTML-5-is-not-ready-to-replace-Silverlight.aspx (through Google Sidewiki)

Reblog this post [with Zemanta]

Thursday, March 11, 2010

Google Streetview has now covered The Netherlands

.. including my car

As I blogged earlier: Google Streetview was extending it's reach across my beautiful country. I also noted that some parts were still MIA.

That has changed now.

HANNOVER, GERMANY - MARCH 03:  People gather i...Image by Getty Images via Daylife

Netherlands are covered

Now one can go across the country in Streetview and see almost any street there is. It is great fun to look at your own house, but you can now also see what that place looks like where you are going for the first time.

Reblog this post [with Zemanta]

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]