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!

2006-12-12

Onion, part 3 (teaser)

Seeing as I haven't had enough free time to write part 3 recently I thought I'd post this little teaser. Would it surprise you to know that this very diagram generated into code and I was able to run it?

The signals on the ShowWelcomeMessage had to be hand coded, but hopefully I will be able to get some kind of custom code generation plugin to get the signals auto generated in future.

2006-12-11

Seven deadly sins of application development

Here is a list off the top of my head

1 - Ugly code!

Why do some people set local variables to null when they have finished with them? This is .NET! The garbage collector will collect "unreferenced" objects when it is ready, an object is unreferenced if you no longer use the variable that holds the reference to it!

Why do people name variables so poorly? Firstly I *hate* Hungarian notation. C# is a strongly typed language so I cannot multiply a boolean by a string, so why do people use variable names like "bIsMale" and "iAge"?


2 - Catching all exceptions

An exception is something you expect to happen, but shouldn't happen if all goes well. If such an exception occurs you might know how to solve the problem and enable your application to continue, but if the exception type was unexpected how can you possibly know the cause of the error or what state your application is now in? Therefore I hate code like this

try
{
DoSomething();
}
catch
{
}

3 - Accessing camelCase members

I really dislike it when people use camelCase names for private members with no property accessor. Sure, at the moment you don't need to execute any code whenever that member is read/written, but in future you might! If you name your private members with PascalCase instead then it becomes very easy to implement a property by changing it to camelCase instead, and then every reference to that member will automatically access your property instead.


4 - No testing

If something is so simple that it cannot possibly fail, it will fail! If you can't see why something could possibly fail it is because you haven't tested it, once you have tested it you will see all sorts of ways to make your code fail that you had not previously thought of.


5 - Implementing anticipated features

I hate being asked to write features that "might be needed in the future". Inevitably they are rarely needed and merely take away time from the development of features that are.


6 - Being told how to do something rather than what is needed

Managers who used to be programmers are the worst for this one! They see a requirement and the only way they can think of describing it is in a technical way. 1) Do this, 2) Do that, 3) Check this. From this description you have to reverse engineer what they are trying to achieve in order to come up with the original requirement. It's a bit like Chinese whisper, and you never end up with the original requirement. Worse still, you don't know why the customer requires the feature.


7 - Unreasonable deadlines

It is surprising how quickly an unmissable deadline is rescheduled when it is missed, this is usually a sign of a deadline that has been concocted for no apparent reason other than to make your manager look good. Unreasonable deadlines just stress your developers, and humans don't work so well under stress.

Have time off work, you will be more productive than if you work lots of hours. Don't let the consequences of failure drive your coding, write the best possible solution given a reasonable amount of time to develop it. I hate the "just get it out of the door" types, but perfectionists must also note that an undelivered application is far from perfection!

2006-12-08

Onion, part 2

Going beyond wizard interfaces

If someone had said to me "Process oriented application", in the past I would have thought to myself "Wizard-like interface". Whereas I find "Wizards" very useful in certain situations I also find that they are too time intensive for a user who knows what they want to do, how to do it, and just want to get on and do it!

The thing is, I think an application layer should be process driven. The business objects layer is there in order to represent the logical business entities of the application, and the application layer should be there to drive the logical flow of the users' interaction with those objects. So, the question is "How do we implement a process oriented framework without enforcing a wizard-like interface?" The answer I think is to use Signals.

Signals

The process may imply that there is always a specific path through an application. Although the user may influence that path by selection options along the way, it is also necessary to allow the user to perform a selection of adhoc actions at any given time, these tasks should in some way relate to the action that the user is currently performing. For example, whilst selecting a customer from a list it might be reasonable for the user to decide to view the details of one of the customers within the list before deciding they have chosen the correct one, or to edit the customer's details if they should spot a mistake.

So what exactly is a Signal and how would it work? Think of a signal as a method. Instead of this method being assigned directly to a class and therefore available to each instance of that class, a signal is a more of a "command" object which may be sent to a target object instance. The properties of this command object are akin to the parameters of a method.

You may ask yourself "If a Signal is so similar to a method, why wouldn't I just use a method instead?". Well, there are a number of benefits:

  • Either the SignalTarget is aware of the Signal type and reacts accordingly upon receiving it, or the Signal is aware of the SignalTarget and performs an operation upon it.
    • It is possible to add methods to specific instances rather than only at class level.
    • It is possible to extend the functionality of classes without having to alter their source code, which is excellent for allowing customers to have customisations written without having to resort to checking conditional compiler defines.
    • It allows you to keep the source of the target class "clean" rather than polluting it with methods for every possible feature.
  • A signal may be received by more than one type of target. Using this approach helps to introduce a kind of "business dictionary" for the application. If the same term is used throughout the application (eg "Stream to file") the user will find it much easier to understand the application.
  • Using a signal approach makes it very easy to ascertain which operations are available for a given target. This also allows us effectively to hide or disable a method given the current state of the object. A method based approach would require the use of reflection, and also a way of determining which methods of the class are their for implementation purposes and which are there to serve the user.
  • Signals may be registered from dynamically loaded assemblies, providing the ability to customise object behaviour at runtime.
  • Signal permissions may be used to introduce role based behaviour. The available actions depend entirely on the roles of the person using the application.
So, sermon over, how do they work?

Firstly I wanted to avoid instances. Signals are a way of behaving, a "thing you do" rather than a "thing you are", therefore a Signal should be an interface.

Signal

Not surprisingly I have chosen the name ISignal for this interface, and it has only a single member:
  • Execute(ISignalTarget)
This method should be invoked by the ISignalTarget to which the signal has been sent. This way the ISignalTarget always has "first refusal" and may decide whether or not to allow the signal to continue.

Signal target

The ISignalTarget interface is used to identify an object as a target for signals. This interface has two methods:
  • AcceptSignal(ISignal)
  • GetSignalPermission(ISignalFactory) : SignalPermission
AcceptSignal is executed when a signal is sent to an instance of ISignalTarget. This is where the class itself is able to react to a received signal if it is explicitly aware of that signal type. By default this method should execute signal.Execute(this) so that the signal (which may be unknown to the target) may perform any actions.

GetSignalPermission is a way of determining compatibility between the ISignal and the ISignalTarget. It returns one of the following values:
  • Supported: The ISignalTarget is aware of the signal type and will perform an action in response to receiving it, therefore the target and signal are compatible.
  • Unknown: The ISignalTarget is unaware of the signal type. Therefore the target and signal are only compatible if the signal itself indicates that this is the case.
  • Prohibited: The ISignalTarget is aware of the signal type, and regardless of what the signal indicates it will not accept the signal, therefore the signal and target and incompatible.
  • Disabled: The ISignalTarget is aware of the signal type. Although this signal is normally accepted it will not be accepted at this point in time, this could be due to the current state of the ISignalTarget (for example, "Archived"), therefore the signal and target are compatible but the signal may not be sent.

ISignalFactory

As you probably know, in .NET there is no (easy) way to implement virtual class methods. Class methods would have been very useful in this scenario because it is possible for a signal to indicate support for a target, yet it makes no sense to create an instance of every ISignal for the purpose of performing this query. In fact memory consumption is not the only reason to not take this approach:
  1. We have no way of knowing how to create an instance of the ISignal type. We could assume that we should always look for a parameterless constructor and invoke it using reflection, but this would not work for classes which require a parameter in their constructor. For example, if instances of the class belong to some kind of "object space" or a transaction which must be passed as a parameter.
  2. If we did create an instance of every type they would be used only for obtaining permissions. In a multi-user environment such as remoting or ASP .NET applications those same instances would be used by every thread, so setting their properties (aka method parameters) would be nonsense.
This is the reason I opted for an ISignalFactory interface. If .NET had the ability to handle virtual class methods then this would not have been necessary, but it's better to work around a limitation than to give up and complain about it...

The ISignalFactory interface has the following methods:
  • GetSignalPermission(ISignalTarget): SignalPermission - Identical to the behaviour of the ISignalTarget method.
  • CreateSignal(object applicationData): ISignal - Creates an instance of the ISignal to send to the target. The "applicationData" can be an object, struct, or whatever the developer decides is necessary to pass to the factory in order to construct an instance (Such as an "object space" or a transaction object of some kind).
  • Category : string - This can take any format the developer wishes and may be used to categorise signals within the UI. For example "\MainMenu\File\Edit" would indicate to the UI layer that the signal should appear in the File->Edit menu of the application's main menu.
  • DisplayName : string - This is the text to display in the UI, for example "Copy". This could either be the literal text to display or the identity of a string resource within the UI to retrieve and display.
  • UniqueId : string - This is a way of uniquely identifying the signal, it could be the namespace + classname, or better still a Guid as this will never change.

Signal catalogue

There is one final piece to the Signal jigsaw, the ISignalCatalogue. I have implemented a class for this item as it has very specific behaviour and I can't see any way in which it would be useful to modify it. Despite this I have created an ISignalCatalogue interface for the purpose of interacting with the class just in case somebody wants to write an alternative implementation.

The signal catalogue is a single point from which it is possible to get a list of compatible signal factories and signal targets. My implementation scans all loaded assemblies during its construction and looks for classes which implement ISignalFactory and creates an instance, this instance is then held in a list owned by the catalogue. It is also possible to manually register an instance or an assembly in case you need to dynamically load signals/factories from a DLL in order to provide customisation.

Once the signal factory is created it provides the following functionality:
  1. Given an ISignalTarget it will return a list of compatible ISignalFactory instances.
  2. Given an ISignalTarget and an ISignalFactory it will return a "SignalPermission".
  3. Given the UniqueId of an ISignalFactory it will return the ISignalFactory so that an ISignal may be created and sent to the target.
The signal catalogue is used as the single point of reference for obtaining compatibility because it performs the task of querying both target and factory before determining the result.

A SignalPermission is obtained from both the ISignalFatory and the ISignalTarget. The combinations listed below will provide the specified result:
  • Factory = Prohibited : Prohibited
  • Factory = Unknown : Returns the permission of the ISignalTarget.
  • Factory = Supported:
    • Target = Disabled : Disabled
    • Target = Prohibited : Prohibited
    • Target = Supported : Supported
    • Target = Unknown : Supported
  • Factory = Disabled:
    • Target = Supported : Disabled
    • Target = Unknown : Disabled
    • Target = Disabled : Disabled
    • Target = Prohibited : Prohibited

Conclusion

It is now easy to find a list of "commands" that are compatible with any given ISignalTarget by retrieving a collection of ISignalFactory. The information from this list of factories may be presented in the UI for the user to choose from, and may be logically grouped by the UI through use of the factories' "Category". In fact it would also be possible to differentiate signals available to the UI from internal signals via this category, maybe anything starting with "\UI" should be displayed.

If a "Process" within the application layer implements ISignalTarget then we now have the ability to specify within our application what exactly the user can do with that process. Rather than having "Next" and "Back" methods on our process we can implement "Next", "Back", "Okay", "Finish", "Confirm" or whatever type signals are most appropriate for the given task. In addition it is possible to display to the user a menu of possible actions, a group of actions (similar to the XP control panel) to the side of the form showing related tasks they could perform.

Most importantly though these signals provide a way of telling a physically separate layer what commands are available without that layer having to have any knowledge of the signal or the target. This makes it possible not only to have separate layers on a single machine, but also very easy to stream the information as XML to a physically separate layer on a client machine.

Summary

In this entry I have discussed a technique that can be used for many purposes, but in this case it will be used to aid user interaction with the application. In the next in my mini series I will describe the process layer in more detail, how it operates, and how to allow the user to interact with the information presented to them. Keep an eye out of Onion part #3 :-)

2006-12-02

Onion

An onion has layers...
...Shrek

In the beginning

When I first started writing applications they would typically be a single program editing a single datasource. As time went on this changed because people wanted to share data, so client/server applications appeared.

It didn't stop there though, N-Tier applications became much more common. Applications were typically split up like this:

RDBMS--DAL--Business classes--UI

Due to the fact that I use ECO for my business layer , and that ECO has the DAL built in, the illustration for me would look something like:

RDBMS--Business classes (ECO)--UI

Thinking of business problems as classes instead of tables really helps to simplify your design, so I have been very happy writing applications this way for some time now.


The application layer

In December 2005 I was tasked with the job of writing quite a complicated Compact Framework application. Although this application was going to be complicated it needed to be very simple to use, as the customer's employees were not all computer literate.

I decided to take a wizard-like approach to the application. This had the benefit of guiding the users through their daily tasks in a way that offered them options which were relevant to what they are currently doing instead of overloading them with options in a menu. However, this approach was not only beneficial to my customer's users, it taught me something I think is very valuable. Applications should have an extra layer!

The problem is that many programmers will design their UI to reflect their database layout or their business classes. For example, a developer might create a "Vehicle" form, but when presented with this form what would a user do?
  1. View its service history?
  2. View a planned service schedule?
  3. View purchase + depreciation information?
  4. Hire it out to a customer?
If the developer does not know what the user wants to do with the vehicle in question then the only sensible thing to do is to show all of this information (maybe in tabs) and allow the user to do anything they want isn't it? Can you imagine a person who is non computer literate being shown such a complicated form and being expected to to just "get on with it"? I hope your training and support departments are well staffed! :-)

The solution is to present the user with a task instead of an instance of a business class. So instead of editing information within a complicated Vehicle form the user will enter a few basic details in order to complete a "TransferVehicleOwnershipActivity". The word "Activity" could easily be replaced with something like "Task", "Action", or "Process", but the general idea is that you present the user with something to do rather than presenting them with the object on which their actions will be performed.

Code in the UI

There are some things that simply don't belong in your business classes and this sort of code often gets written into the UI layer. Code in the UI layer should only concern itself with UI related issues, such as enabling/disabling controls. An example of this would be some kind of an email client.

When you open a message in your inbox it is automatically marked as read, but where should this code be written? I'd certainly agree that you should have a method on your IncomingMessage class
void MarkAsRead()
but this method still needs to be invoked! You may find yourself reaching for the Form.Load event, and I really wouldn't blame you if you did.
void IncomingMessageForm_Load(object sender, EventArgs e)
{
this.IncomingMessage.MarkAsRead();
}
but what if in the future you needed to create a web based version of your application? Obviously you'd expect to have to write some code into your WebForms but again this should be code to handle things like enabling/disabling UI controls. To get the same functionality you'd have to copy the code from your WinForms application.

Once you have finished copying all of the logic from your WinForms application and you have a functionally identical WebForms application what next? Someone changes one of the UI applications and forgets to update the other! We should have known better, having code like this causes a bad smell...
void IncomingMessageForm_Load(object sender, EventArgs e)
{
//If you update this code make sure you
//update IncomingMessage.aspx!
this.IncomingMessage.MarkAsRead();
}
This is exactly the sort of scenario that is easily solved by having an application layer!


Onions have layers

Onions have layers. This is why I have decided to name my application framework "Onion". I'll be playing around with Onion in my spare time and blogging about my experiences and decisions, so keep an eye out for part #2!