Posts

Showing posts from 2008

Domain driven design, Test driven design

I was just reading through the VBUG events list when I came across an event entitled "Domain driven design approach, using unit testing". "Sounds interesting!" I thought to myself, I hope I can make it! As I started to read it I thought it looked familiar. At that point I realised it was me doing the talk! So hopefully I will be able to make it :-) The posting is here . If you come along make sure you say "Hello".

Computer music

You may already know that I used to own a Commodore 64, and (as is nearly everyone else who ever owned one) I am still very passionate about the music people used to produce on it. The question "Which was your favourite Commodore 64 tune" is a very hard one to answer as there are so many good ones out there, and people tend to go for the same short list "Delta", "Sanxion", etc. However, recently I was creating some ambient background music for a presentation video. It started off a bit like a Jarre tune, but as I started to add in the percussion (for which I used samples of car doors slamming) it started to remind me of a tune from an old C64 game; "Tetris". After downloading it and listening to it endlessly over and over as I write code I have come to a conclusion; TETRIS is my favourite C64 tune! It is just so unique, and unlike many other C64 tunes it hasn't aged, and doesn't actually sound that much like a C64 tune at all! Whenever...

FireBird - Did it burn me?

This morning I spent an hour on the phone to Microsoft support. I tried to log into my machine only to see the error message The user profile service failed the logon. User profile cannot be loaded. The guy on the phone got me to put my Vista install DVD into the drive, boot from that, go to system-recovery, and revert to a restore point. Worked nicely. The thing is, why did this happen? The only thing I can think of is the open source Firebird DB server. I installed it on Sunday to get an old app to run (installed as app, not service). I didn't install the control panel plugin due to a warning on the site telling me not to install it on Vista or it will trash my Control Panel. I suppose the warning about the control panel should have been enough to put me off. Still, it works now. I just wont be installing it again, at least for some time.

The importance of clarity

I wrote and now maintain a Pocket PC app for Imperial Tobacco (yes, despite supporting the ban on smoking in public places). It is important that the date/time on the PPC is accurate so part of the business flow is to get the user to check the date/time immediately after they log in. Despite this step we were getting invalid dates back from their collected data, in all cases it was always one day ahead of the correct time. We have recently introduced various additional common sense checks such as "You have missed a working day, are you sure?" etc, but the change that will have the biggest affect is the one that was the smallest to change. When the user enters the current date/time if it is less than the last known date/time on the server (sent in their database of work to do) I showed a message saying it was incorrect. The message read "The date you have entered is invalid" At this point the user looks at the date they have entered, thinks "but the date is r...

The ubiquitous language

One of the most important things to do when designing a system for a customer is to to try create a common business language between you and the people who understand the problem domain. A lack of what is known as "the ubiquitous language" can result in misunderstandings and a failed project. I had a real life experience of a ubiquitious language failure yesterday. My brother went to the shop to buy some credit for his phone and offered to take my children with him to buy sweets. When they got back my son asked me "How come uncle Stephen was able to buy credit for his phone?" When I asked what he was talking about he described the sign on the wall in the shop, it read "Please do not ask for credit as refusal often offends"

Spiders in lieu of payment

Very funny :-) http://www.quoted4truth.com/articles/I-do-not-have-any-money-so-am-sending-you-this-drawing-I-did-of-a-spider-instead and you can bid for the picture here http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=190265903424 I wish I had thought of ebay'ing it :-)

How I would like to write code

Image
Aspect Oriented Programming looks great. It's something I have always wanted to use, but I avoid it because it doesn't work exactly how I would like it to. The first thing I want to avoid is lots of reflection at runtime (compile time is fine), it is for this reason I have mainly been interested in PostSharp . PostSharp looks great! You decorate your class with attributes that you create yourself. After compiling your assembly PostSharp inspects the result for Attributes that are descended from one of its own special PostSharp AOP classes. When it sees these attributes it modifys your code in a specific way. To use the same example as everyone else in the world (yawn) you could create an attribute from the method-boundard attribute. Override the methods declared on that attribute for entry/exit of the method, and write some code in there to write to the IDE's output window using System.Diagnostics.Debug.WriteLine(). Now when I add that attribute to a method on one of my cla...

Sufficient architecture

I have a friend who once decided to teach himself VB. We had a mutual friend who was the manager of a video shop so he decided to write some new software for him. He started off by creating an MS Access database to hold the data for his application. Each week I'd pop around to his house and he'd have MS Access open, reworking his tables etc. After a few months I asked "Have you started to write the app yet?". "No, not yet." He replied, "I am trying to get the DB right first, then I will get onto writing the application". I asked what he meant by getting the DB right. He explained that he wanted to make this the best video-hire software ever, and that I should hear about some of the features that are going into it as a result of the DB structure he has made. Record the cast of the film. Record the director, producer etc. Record the genre; horror, comedy, etc. Record film information for films due to be released in the future. All sorts of stu...

Accommodation manager - runtime error

I've just spotted something I omitted before zipping up my AccommodationManager app and making it available. When you run the app in Release mode you will experience SQL errors. These errors are intermittent, and a query that worked only seconds ago might not always work. The reason for this is that ECO executes all queries within a transaction; SQLite creates a journal file for every transaction and then deletes it when done; and my anti-virus decides it wants to take a look at this new journal file to see what's inside it; resulting in SQLite not being able to open its own journal file exclusively. This was something I noticed a while ago in another ECO+SQLite app of mine and the guy who writes the library spent a couple of hours with me on MSN trying to work out what the problem was (he had a fix to me by the next morning!). Anyway, I have updated the project so that the connection string tells SQLite not to delete the journal file when it has finished with it, as a conse...

ECO, Winforms, ASP.NET, and WCF

The technologies I used in an app I wrote for friends recently. The app manages properties at different locations, bookings, and tariffs. In addition to this the application (which uses SQLite) connects to their website using WCF and updates their database so that people can check prices and availability. I need to get them using it now so that there is data available by the time I put up their website .

Implementing complex unit testing with IoC

I have a method that looks something like this public void DoSomething(SomeClass someInstance, User user) {   var persistence = someInstance.AsIObject.GetEcoService<IPersistenceService>();   persistence.Unload(someInstance.AsIObject());      if (someInstance.CurrentUser != null)     throw new ..........;   someInstance.CurrentUser = user;   persistence.UpdateDatabase(someInstance); } This unloads the local cache before ensuring someInstance.CurrentUser == null, it then sets someInstance.CurrentUser and updates the DB. The unit test I wanted would check what happens when two users try to perform this at the same time. What I wanted was User A: Unload User B: Unload User A: Check == null, it is User B: Check == null, it is User A: Change + update DB User B: Change + update DB + experience a lock exception What I didn't want was User A: Unload User B: Unload User A: Check == null, it is User A: Change +...

Unit testing security

Following on from my previous post about using(Tricks) here is an example which makes writing test cases easier rather than just for making your code nicely formatted. Take a look at the following test which ensures Article.Publish sets the PublishedDate correctly: [TestMethod] public void PublishedDateIsSet() {   //Create the EcoSpace, set its PMapper to a memory mapper   var ecoSpace = TestHelper.EcoSpace.Create();   //Creat an article   var article = new Article(ecoSpace);   //Create our Rhino Mocks repository   var mocks = new MockRepository();   //Mock the date/time to give us a predictable value   var mockDateTimeService = mocks.StrictMock<IDateTimeService>();   ecoSpace.RegisterEcoService(typeof(IDateTimeService), mockDateTimeService);   //Get a date/time to return from the mock DateTimeService   var now = DateTime.Now;   using (mocks.Record())  ...

Single instance application - revisited

Not so long ago I posted a solution to having a single-instance application. Rather than just preventing secondary instances from running the requirement was to have the 2nd instance pass its runtime parameters onto the 1st instance so that it can process them. My solution used remoting on the local machine. This appeared to work very well until recently when I needed an OpenFileDialog. Attempting to show the dialog resulted in an error about COM thread apartments. So, it wasn't THE solution. After a bit of research I decided to use named pipes instead. This meant I had to upgrade my app from .NET 2 to 3.5, but I think it is worth it. To implement the feature in an app you need to do 2 things. First you need to realize the interface ISingleInstanceApplicationMainForm on your app's main form in order to accept command line arguments from any subsequently started instances. Next you need to change your Program.Main method like so: [STAThread] static void Main(string[] a...

using(TricksToFormatYourCodeNicely)

I've been writing a data importer which takes a specific data input format and outputs XML, this XML is then imported within my application. What annoyed me was the way in which the source code was formatted.... writer.WriteStartElement("data"); writer.WriteAttributeString("1", "1"); writer.WriteAttributeString("2", "2"); writer.WriteAttributeString("3", "3"); writer.WriteStartElement("systemData"); writer.WriteAttributeString("a", "a"); writer.WriteAttributeString("b", "b"); writer.WriteEndElement();//systemData writer.WriteEndElement();//data It just didn't look nice. I thought about splitting it into separate methods, but most of the time this would have been overkill as the methods would have been very short. Instead I wrote an extension method on XmlWriter: public static class XmlWriterHelper {   public static IDisposable StartElement(this X...

Parameterised queries in ECO

Whenever I generate OCL queries in code I find myself having to escape user input in order to avoid making the query invalid, or allowing malicious input. I've decided instead to use the ECO equivalent of parameterised queries (variables in ECO) and here is the result. public static string CreateParameterisedQuery(   this IEcoServiceProvider serviceProvider,   string query,   out IModifiableVariableList vars,   params object[] args) {   vars = serviceProvider.GetEcoService<IVariableFactoryService>().CreateVariableList();   for (int varIndex = 0; varIndex < args.Length; varIndex++)   {     string variableName = "autoVar_" + varIndex.ToString();     query = query.Replace("{" + varIndex.ToString() + "}", variableName);     vars.AddConstant(variableName, args[varIndex]);   }   return query; } To use thi...

User authentication in SilverLight

I wanted to know how to authenticate users in a SilverLight app using their Windows login info. 01: Set the authentication mode to Windows and <deny users="?"/> in <system.web> within web.config 02: Move the silverlight control to Default.aspx and set that as your start page 03: Add the following Page_Load code protected void Page_Load(object sender, EventArgs e) { IPrincipal p = HttpContext.Current.User; if (p == null) throw new SecurityException("No current user"); if (!(p is WindowsPrincipal)) throw new SecurityException("Not a windows user"); if (!p.Identity.IsAuthenticated) throw new SecurityException("Not authenticated"); Xaml1.InitParameters = string.Format("user={0},session={1}", p.Identity.Name, Session.SessionID); } 04: In app.xaml.cs you can now read the InitParameters using e.InitParameters in the Application_Startup method.

No more free disk space - Vista

My computer was recently running out of disk space. I couldn't believe it, I have 175GB on my partition, how could I fill it so quickly? I was considering buying a 500GB external drive to store my home videos etc on (which is where I assumed all the space was being taken) and earlier today I nearly went out and bought one too! I just decided to check where all that space was being taken up. Here are the folders on C and their sizes in GB apps 2.76 data 40.7 msocache 0.7 otherdata 0.8 program files 9.16 program data 0.9 users 1.64 windows 13.8 That's a total of 70.46GB, but Windows was reporting 173GB in use! I ran scan disk etc, no luck! Where was all the space being used? The answer was System Restore! After reading this article I realised my restore data was using 90GB of data! What a waste! I have now limited it to 10GB maximum. Can you believe that? It's ridiculous! Luckily I have just saved myself £70!

The contract name could not be found in the list of contracts implemented by the service

When trying to add a service reference to my SilverLight project I kept getting this error message The contract name xxxxxxx could not be found in the list of contracts implemented by the service I looked around the web and couldn't find anything of any use (yes, I had added ServiceContract to my interface). The solution was really simple! In my Web.Config I had the wrong interface defined. IApplicationService was defined in another assembly, one I had added a namespace to, so I additionally needed to add the namespace before the interface name. All I then had to do was to add the following attribute to the service implementing the interface and it seemed to import fine. [AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]

Validating NumericUpDown on compact framework

A customer requested that instead of my NumericUpDown controls silently capping the input value within the Minimum..Maximum range it instead showed an error message telling the user their input is incorrect and that they need to alter it. I was a bit annoyed to see that NumericUpDown.Validating is never called on the compact framework, in addition there was no way to get the input value and either accept or reject it before it is applied to its data bindings. There's an article here which shows how to implement auto-select text when the NumericUpDown receives focus and I have been using it since Feb 2006. I decided to extend upon the techniques within it to implement the Validating event. My goal was to fire the Validating event before the value is applied to all data-bindings, but also to allow the programmer to read NumericUpDown.Value in order to determine the new value. To do this I had to replace the WndProc of the control so that I could handle the WM_UPDOWN_NOTIFYVALUECH...

Single instance application

An app I am working on needs to be a single instance. It is associated with certain file extensions so that when I select a character or license file it will be imported automatically. When the user buys a character or license (etc) from the website it will be downloaded and opened, and then imported. Obviously it is a pretty poor user experience if they have to close the app, download, close the app, download... So what I really needed was a way to have the 2nd instance of the application to invoke the first instance and pass the command line parameters. Here is a simple solution I implemented using remoting. 01: An interface public interface ISingleInstance { void Execute(string[] args); } 02: A class that implements the interface public class SingleInstance : MarshalByRefObject, ISingleInstance {   private static object SyncRoot = new object();   private static Form1 MainForm;   static SingleInstance()   {     Applicat...

More leak fixes

I have changed the DirtyObjectCatcher so that it initially only hooks Form.Disposed - Automatically disposes the DirtyObjectCatcher Form.Closed - Unhooks all additional form events (below) Form.Shown - To hook additional form events (below) ==Additional form events== Form.Activated Form.MdiParent.Activated Form.MdiChildActivate The additional events are to ensure that the DirtyObjectCatcher's undo block is moved to the top. The reason that these events are now unhooked is so that there is no strong event references from the application's main form (Form.MdiParent) to this component, keeping it alive. Now we only have long-term event references from the owning form itself. Really though this is just an added precaution against something I may not have thought of :-) The true memory saver comes from only holding a WeakReference to the owning form. Otherwise in an MDI application we have the following MainForm.MdiChildActivate->DirtyObjectCatcher->Form In such a case c...

Memory leaks

As a follow up to yesterday's post here is a list of problems I found... 01: The following code for some reason causes the form holding the DirtyObjectCatcher to remain referenced. if (Owner.MdiParent != null) { Owner.MdiParent.Activated += new EventHandler(MdiParent_Activated); Owner.MdiParent.MdiChildActivate += new EventHandler(MdiParent_MdiChildActivate); } The odd thing about this is that it really is the events that matter! I subscribe Shown, Disposed, Activated on the Owner (which is a form) and that doesn't cause the same behaviour. The reason is that the Owner normally gets disposed and takes out the DirtyObjectCatcher with it, however, if I have Owner.MdiParent events referencing DirtyObjectCatcher then the form will never get disposed because DirtyObjectCatcher has a strong reference to Owner. Maybe I should change it, but for now the Shown and Activated events seem to be doing the trick. 02: This one was a real pain! DirtyObjectCatcher creates its own Undo...

DirtyObjectCatcher

Oh boy, what a nightmare! After days of messing around I finally found where the memory leak is in my app, it was in DirtyObjectCatcher! The DirtyObjectCatcher used to subscribe to the DirtyListService, so that it was notified whenever an object was made dirty. I experienced this problem... 01: User creates a "Call" to a customer site. 02: User edits a purchase order. 03: Save purchase order (merges the undo block to the Call undo block and closes the form) 04: Edit the purchase order again from the Call form The PurchaseOrder is already dirty so it wont get triggered again, this used to result in no constraints being checked etc and the possibility of entering dodgy data. The solution at the time was to have a static list in DirtyObjectCatcher private List Instances; whenever a new instance was created it would be added, whenever Dispose was called it would be removed. I then hooked into the cache chain and whenever a value changed I would call a static method on DirtyObjec...

TeamCoherence - disaster!

That's it, my short evaluation of TC is over! Problem 1: I emailed support with a question weeks ago, didn't get a response. Not impressed. Problem 2: I reinstalled my O/S recently so had to restore my version control folder. When I try to check files out I now get an "Object not found" error, whatever that means? Some searching reveals it is a bug that has been fixed in the version I have, I beg to differ. Problem 3: This one was the worst! I use TC client for a customer already which is why I decided to try out the server. I connected to the customer server, checked out loads of files, upgraded my VS2005 project to VS2008 and then checked everything back in. What a disaster! TC had replaced the source in the customer files with source from my private local server! I couldn't believe it! As I looked through Assembly.cs files I could see WinForm code from the last project I worked on locally! This is obviously bad because I had exposed source code from one concern...

TimeBasedSyncHandler

I recently had to tweak my remote persistence server settings. I noticed that I had leaft the SyncHandler.HistoryLength at the default value of 10,000 items. This was overkill because my clients sync every 3 seconds. I thought maybe I should drop this down to about 100, that should be okay? Each client only does about one update every few minutes so I it should, right? Problem is not all of my users are people. One user is a messenger service which looks for unsent messages, sends them one at a time, marking each in turn as sent and updating the database. This gets run every five minutes so probably sends about fifty messages at the most, but what if someone decides to change it to ten minutes, or thirty? So maybe I should increase the HistoryLength to about 200? Then there is the other client, this one syncs with an external database. This could perform hundreds of updates every minute. If the messenger is set to run every thirty minutes...I'm not sure what a good History...

Making a generic type from a Type

List<Person> p = new List<Person>(); This works fine, but what about this? Type someType = typeof(Person); List<someType> p = new List<someType>(); Nope! But you can do this... Type genericType = typeof(List<>).MakeGenericType(someType); Why would I want to? Because I am creating a tool that generates plain old .NET objects from an EcoSpace's model, and I wanted to implement multi-role association ends as public List<Building> RoleName; rather than just public Building[] RoleName;

Returning a binary respose in ASP MVC RC3

In a previous post I showed how to return a binary file from a controller action, well, this no longer works in release candidate 3 of the framework. Instead you have to create a new ActionResult descendant to do the job for you. This is how I did it.... return new BinaryResult(data, Path.GetFileName(productFileName)); and the class is implemented like so: public class BinaryResult : ActionResult { private string ClientFileName; private byte[] Data; private string VirtualFileName; public BinaryResult(string virtualFileName, string clientFileName) { if (string.IsNullOrEmpty(virtualFileName)) throw new ArgumentNullException("VirtualFileName"); if (string.IsNullOrEmpty(clientFileName)) throw new ArgumentNullException("ClientFileName"); ClientFileName = clientFileName; VirtualFileName = virtualFileName; } public BinaryResult(byte[] data, string clientFileName) { if (data == null) throw new ArgumentNullException(...

ASP MVC preview 3 released

I'm trying to upgrade from Preview 2 to Preview 3. I think the idea of having each action return an ActionResult was a good one, so far it has actually made my code slightly smaller. What I don't understand though is why Html.Select seems to have disappeared... Compilation Error Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately. Compiler Error Message: CS1501: No overload for method 'Select' takes '5' arguments Source Error: Line 8: Product Line 9: Line 10: Line 11: Line 12: When I go into the APX and type Html. there is no Select method listed along with the other options! Where is it?

Hooking into ECO multi-association events

Although I have not (yet) needed this myself I can see myself needing it in the future and the question has been asked before. "Setting HasUserCode=True on a Child.Parent single role does what I want, but how do I handle the scenario where Parent.Children.Add(item) is called on a multirole?" By default you can’t, but with the addition of a single class and a small amount of tweaking you can get it to do what you want! Here is how to do it: 01: Mark Parent.Children’s association end with HasUserCode=True in the modeler and then generate code. 02: In the source code of your class (not within an ECO region) add the following   private EcoMultiAssociation<Child> m_Children; This is a class that does not yet exist, I will show the source code for it later. 02: In the source code locate the "Children" property and change it like so   public IEcoList<Child> Children   {     get    ...