2007-01-19

Testing a website with a root path

This post is really a reminder to myself, so that I can find the information quickly for the next time I reformat my hard drive!

To run a website with a root path in Visual Studio 2005 follow these steps:
  1. Tools->External tools menu
  2. Click Add
  3. Title = Webserver
  4. Command = C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.EXE
  5. Arguments = /port:8080 /path:$(ProjectDir)
  6. Tick "Use output window"
Whenever you need the webserver running just open your project and go to Tools->Webserver.

2007-01-17

Calling base constructors in C#

I occasionally find it annoying that I cannot specify at which point in a class's constructor I wish to invoke the base constructor. Having C# always invoke it before any of the code in my descendant constructor is executed sometimes causes me problems.

Considering .NET is capable of calling the ancestor constructor at any point I wondered why C# wont allow it. I contacted Anders Hejlsberg and he was kind enough to reply, unfortunately he seems to have answered a question I didn't ask :-)

Anyway, I have been deleting some old emails today and I came across his response, which he gave me permission to publish:

The problem with Delphi's model (allowing constructors to be called on
an already constructed object) is that it makes it impossible to have
provably immutable objects. Immutability is an important concept because
it allows applications to hand objects to an external party without
first copying those objects and still have a guarantee that the objects
won't be modified. If constructors can be called on already constructed
objects it obviously isn't possible to make such guarantees. In Delphi's
case that may be ok since Delphi doesn't really make type safety
guarantees anyway (you can cast any object reference to a
pointer-to-something and start poking away), but .NET goes further with
type safety and this would be a big hole.

There, now get out of my head ;-)

Anders

2007-01-11

SQL Server amazes me!

Well, SQL Server amazes me, but not because I am impressed!

Today I wrote an application that does the following:
01) Find all ZIP files in a specific folder
02) Open each ZIP file in turn
03) Extract an XML file from the ZIP into an array of bytes
04) Insert that data into a table

There are 1,978 files in this folder and the XML within each ZIP file is around 2MB in size.

I ran this app and was really surprised at how soon my PC started to crawl, it was so slow that it was taking over 10 seconds to switch between MSN and a Skype text-chat window. So I decided to monitor the process.....

Importing the zip data into SQL Server took a total of 19 minutes and 15 seconds (this includes unzip time). What concerns me is that SQL Server's RAM usage went up to 830MB at its peak, this is what was crippling my PC. Twenty minutes after my app had finished SqlSevr.exe was still holding over 700MB of RAM, I then restarted my PC. SQL Server was using more RAM than I had available and was forcing my PC to use virtual memory!

So I decided to try FireBird 2.0

Importing the zip data into FB took a total of 15 minutes and 15 seconds (again including unzip time). RAM usage for FB started at 21MB but dropped to 16MB at home point within the first 5 minutes. It's memory consumption remained at 16MB.

In both cases I was creating + committing a transaction around each INSERT command. In fact it was the exact same code, I just did a search + replace from Sql to Fb.

Amazing!

2007-01-02

DaDa

Today my baby girl looked at me, said "DaDa" for the first time ever, and then giggled. What a great day! :-)

2006-12-27

Delegates

I just remembered another technique for calling methods discovered via reflection! It is possible to convert a MethodInfo to a delegate and call it, this is just as fast as calling the method directly. So if you have a method that you call often which was discovered via reflection you should try this....

private delegate bool DoSomethingDelegate(object a, object b);

MethodInfo methodInfo = type.GetMethod(.........);
DoSomethingDelegate method =
(DoSomethingDelegate)
Delegate.CreateDelegate(typeof(DoSomethingDelegate), methodInfo);

for (int i = 0; i < 1000000, i++)
method(this, this);

2006-12-26

Onion, more on signals

I've been trying to think through every type of feature I can that people might want in an application, and then seeing if I can think up a way of implementing it using signals. A couple of days ago I thought up something I couldn't implement using the exact approach I had.

I once wrote an app that had a treeview on the left hand side, the user could drill down to a customer of their choice and then when they clicked on that customer the display would update and show their details. This made me realise that a simple "SelectCustomer" signal would not be sufficient, what I actually needed to do was to have multiple SelectCustomer signals and indicate which customer to select.

The changes I have decided to make are as follows:
  1. I will introduce a struct called SignalCreateParameters. This will hold a string property "Parameters" which may be used to automatically populate some of the properties of the created signal, ie the customer identity.
  2. The signal factory will first be asked to populate a list of SignalCreateParameters, and then ultimately the target will be provided the opportunity of modifing that list, so that it may add additional items, remove them etc.
  3. Neither the signal factory or target will have GetSignalPermission. Instead the SignalCreateParameters will have a SignalPermission property so that individual customers may be disabled, removed etc within the list.
I've also decided that I really don't like having an ISignalFactory. I really don't like having to write two classes each time I want to add a single new "thing". Having to write two classes for each new feature is prone to error in my opinion, so I've been looking at using reflection again.

I originally used reflection but decided against it because it required the developer to
  1. Identify that the class is a signal (interface or attribute)
  2. Implement certain methods as static methods with a specific name + parameter list.
I went for the SignalFactory class approach so that I could create a base class and allow the developer to inherit from it, this would make it very clear which methods needed to be implemented. However I think that the penalty of developing two classes each time outweighs the time it takes to learn the method signatures required (1 constructor + 1 optional method).

So I think I will now remove the ISignalFactory part of the framework. The only thing I really need to consider is performance. On my 2.Ghz laptop executing a static method directly 1 million times takes 31 milliseconds, whereas via reflection it takes 2,109 milliseconds. This would mean that if there were 1,000 signals and 1,000 simultaneous requests the process would take 2.1 seconds per user. I don't suppose that is too bad really, if anyone has anything further they think I should consider then I'd like to hear from you. Just write to my droopyeyes.com email address (support@)

2006-12-20

Onion, part 3

Women can multitask

No matter how many times you might be told "women can multi-task!" it's just not true, humans can only do one thing at a time. I don’t doubt for a second that my wife's brain can keep track of multiple subjects much better than my single task brain, but at any one point her brain is only concentrating on a single task!

It's exactly the same for software. People may wish to deviate from their current task in order to fulfil some adhoc requirement, but that task is an interruption, it does not occur in parallel to what they were doing before. Once that interruption is over the user of your software wants to pick up where they left off. This is what a process driven (or "task oriented") approach to writing software is about.

Process driven work flow

A process in this context is a single task performed within an application in order to achieve a specific goal. The goal may be just about anything such as "Delete customer", "Print invoice" etc. The process may involve only a single step
  1. Are you sure you wish to delete this customer?
or multiple steps
  1. Select invoice
  2. Select action
  3. Are you sure you want re-print this invoice?
and at various steps,but not necessarily every step, the user may be required to provide some kind of input in order for the process to continue.

During its operation the process may call open the functionality of one or more other processes and act accoring to whether the process completed successfully or was cancelled, after the spawned process has terminated control should be handed back to the original process.

To achieve this we will require some kind of first-on-last-off (FILO) stack of processes. When a process is executed it is added to the stack and becomes the "active" process, when a process is completed or cancelled it is removed from the stack; at this point the re-activated process is informed why it has been re-activated, just in case it needs to act according to how the child process it executed came to be removed from the stack, whether it completed or was cancelled.


Reusable UI

My new (cheap) DVD recorder with hard-disk is pretty good, but you might be surprised with the bit that really impressed me! If I click the Browse button I get a list of contents on the hard-disk and pressing Enter will play the file. If I click the Copy (to DVD) button I see exactly the same UI, however, when I press the Enter button it will copy the file to a DVD instead of playing it.

You might not think this is very impressive, and maybe I'm just weird, but it is the first real-life example of reusable UI I have seen outside of computer software, in fact it is the first example I can recall seeing at all!

We've all heard of patterns in source code. The thing is, there are also patterns in GUI too. Using the example above the pattern is "Select a recording". This GUI asks the user for a specific type of information (which recording they wish to work with), and this input is used by two separate processes, let's say the "PlayRecordingProcess" and the "CopyRecordingProcess". What happens to the recording selected depends completely on what the process is doing.


Interfaces

I decided that instead of writing an ECO framework I would instead write the framework as a set of interfaces and then implement the classes however I want, my first (and only?) implementation will be an ECO one because the state diagrams save me from having to write a lot of code. I also decided that I would avoid properties in these interfaces, using methods instead. This is so that frameworks such as ECO which persist properties to a database wont attempt to persist the values returned by these interfaces.

IProcessStack

The requirements of this interface are

  • GetActiveProcess : IProcess - Gets the IProcess at the top of the stack, the active process

  • GetProcessCount : Integer - Returns the number of processes on the stack

  • GetProcess(Index : Integer) : IProcess - Returns the IProcess at the given index

  • GetProcessParameters : IProcessParameters - Gets a reference to an object that has properties which should be set by the user (explained below)

  • ActiveProcessChanged (event) - Triggered whenever the currently active process changes

  • ProcessParametersChanged (event) - Triggered whenever the ProcessParameters property changes, so that the GUI may react by displaying the currect controls to edit its properties


Initially I struggled with this interface. The class that implements it has an ExecuteProcess method. Originally this method accepted an IProcess parameter, but I didn't like that because an ECO implementation would require the Process to be an ECO object in order to have an association to it, and a remoting implementation would require this Process to be something else. If I asserted this restriction at runtime I would not get strong compile time checking.

Then I had a bit of a eureka moment! I was trying to make the interface a generic representation of the class, and this is not what an interface is for! An interface defines "how do I talk to this class" rather than "this is what this class is". We will never need to execute a process in a generic way, the interface is only there so that we can develop a generic GUI or multiple GUIs. Only the application layer itself will actually need to execute processes, this will be done by signals, processes, and ultimately once at the very start of the application when the main process is executed. So, dilemma over, on I go...

IProcess

This interface is very simple

  • GetProcessStack : IProcessStack - Used to access the process stack

  • GetProcessParameters : IProcessParameters - The ProcessStack will use GetActiveProcess.GetProcessParameters to determine what to present to the user

  • GetInstanceId : String - Used as a unique identifier for this instance. This can be used in a GUI to identify which target a signal should be sent to

  • Activate(ProcessActivationReason) - This method will be called by the ProcessStack whenever the process becomes the active process. The reasons for activation are ProcessExecuted, ActiveProcessCancelled, ActiveProcessCompleted




IProcessParameters

As promised earlier I will explain IProcessParameters. A process may pass through various internal states before reaching its final state and finishing. In some cases the process may be able to obtain all of the information it requires from automated sources (a database, config file, etc) and therefore require nothing from the user. It is more likely however that the user will be required to provide instructions or data at various points.

Whenever this situation occurs the Process will update its ProcessParameters reference and execute the ProcessStack.ProcessParametersChanged event. For example

public class AuthenticateUserParameters : IProcessParameters
{
private string userName;
public string UserName
{
get { return userName; }
set { userName = value; }
}

private string password;
public string Password
{
get { return password; }
set { password = value; }
}

Guid IProcessParameters.GetTypeUniqueIdentifier()
{
return new Guid("DEADBEEF-4F89-11D3-9A0C-0305E82C3301");
}
}

When a process needs to authenticate a user it will need the user to enter a username and password. The process would update its GetProcessParameters reference and then trigger the ProcessParametersChanged event.

At this point the UI layer, which has subscribed to this event, will get the GUID that identifies the type of the parameters, this is just a unique ID that says "I need the user to fill out AuthenticateUserParameters". The UI can then find a suitable control to present to the user and databind it to this object.

Once the user has typed in their username and password they would click a UI element that has been created to represent a signal "OK" or "Login" or something like that. This signal will then be sent to process and this will trigger either an internal state change within the process, or an exception explaining that the username or password is incorrect.

Just like with my clever DVD HDD recorder the UI has absolutely no idea why it is being used, all it knows is that it has been asked for certain information and should present this request in a format acceptible to the user. This UI may therefore be reused throughout the application. The application may ask the user to log in initially, and then at a later time the user may exceed some authority level at which point the same ProcessParameters would be used to capture the username and password of the user’s manager before being allowed to continue.

UI patterns appear all over the place. Here are some examples:

  • Prompt for a username and password

  • Ask the user to confirm or cancel an action. "Are you sure?" Yes/No

  • Select an item from a list

  • Enter a list of numbers in a grid, such as stock quantities during a stock check, or a purchase order




Summary

This one has been pretty conceptual really. What we have now is a clear separation between database, business objects, application layer, and user interface. This separation not only encourages clearly focused code, but also encourages reuse of both processes and composite UI controls.

Using this separation approach also allows us to have multiple UI's without having to implement any logic in the UI (except for code to enable, disable controls etc). In addition this clear separation would allow us to place the layers on different computers. We might have a single database, a farm of application servers, and each client connecting via either the Internet or directly through smart(ish) UI applications, or even a combination of both!