Posts

All users

Yesterday I needed my app to read and write data from a folder to which all users have access. Having the data in the current user's data folder was unacceptible as this would have resulted in duplicate data storages, the MSI installer even generates a compiler warning telling me I shouldn’t use this folder! So I went for Environment.GetFolderPath(SpecialFolder.CommonApplicationData); This seemed to work fine until I tested on Vista, at which point my app would "stop responding" and quit. With a bit of investigation I discovered that CommonApplicationData maps to c:\ProgramData on Vista, which to me looked good until I tried creating a read/write FileStream in that path and received an access denied exception. So, where was I supposed to store my data? Checking each of the values in the SpecialFolder enum I was surprised to see that there doesn&#8217't seem to be a suitable value. So, I reflected over Environment.GetFolderPath and copied the code. I then sta

Embedded Firebird, error trying to write to file

This error has been really annoying me tonight! I have an app that uses Embedded Firebird for its DB so that I don't need to install a DB server. On Vista my app throws an exception "Error trying to write to file (the correct path here)". I recreated the DB on my development machine (XP) and tried running it, it should work, it has for months, but it didn't! The same error too! For the life of me I couldn't work out why it would suddenly stop working on both machines, what did they have in common? I uninstalled stuff, reinstalled it, etc, no joy. The answer on my XP box was simple. I used the local server to create the GDB file + generate my DB structure using ECO. What I hadn't thought of was the fact that the firebird server then holds a file handle open on that GDB file in case I want to use it again. Embedded firebird needs an exclusive lock on the file so this was the problem on my XP box. I wish the error had read something like "Error tryin

Test driven ECO

Here are my latest revelations :-) 01 Instead of having to mock IEcoServiceProvider and IOclPsService in order to avoid DB access simply use PersistenceMapperMemory. This way I can create the objects I want, UpdateDatabase, and then run my tests. It’s much easier to read, and more importantly less typing. 02 My page controllers no longer use an EcoSpace. Instead the code always uses a ServiceProvider property of type IEcoServiceProvider. When I want to test my controller I create an instance and set its ServiceProvider property. Now whenever the controller needs to do anything it will go through the ServiceProvider I specified. This is beneficial for a number of reasons. Firstly it means that I can create an EcoSpace in my test and set its PersistenceMapper to PersistenceMapperMemory before activating it. Secondly I can also opt to pass a mocked IEcoServiceProvider which either returns the real service requested or returns a mocked one. An example of this is that I validate my

ECO, should we mock it?

I watched a video on Rhino Mocks yesterday. What a great framework! Obviously I wanted to know if I could use this with ECO so I thought I'd give it a try. In my website's AccountController there is a method like so public void AttemptLogin(string emailAddress, string password, string redirectUrl) { } Now I could just go ahead and write some OCL to find the user, but instead of doing this I really want to separate the code a bit. So I created a class public class UserRepository {   private readonly IEcoServiceProvider ServiceProvider;   public UserRepository(IEcoServiceProvider serviceProvider)   {     ServiceProvider = serviceProvider;   }   public User GetByEmailAddressAndPassword(string emailAddress, string password)   {     string searchEmail = BusinessClassesHelper.EscapeOcl(emailAddress);     string criteria = string.Format("->select(emailAddress.sqlLikeCaseInsensitive('{0}'))", searchEmail);     return BusinessClassesHelper.SelectFirstObject<Us

Unit testing MonoRail controllers

I spent yesterday finishing off (mostly) my business model, then the end of yesterday + today writing test cases for those classes. Everything was going great, I found at least 3 errors in my code that I hadn’t realised was there and also realised there were a few more things I needed. Then it was time to start testing the controllers in my MonoRail site. What a disaster! Attempt 1: [Test] public void AdminOnly_Home() {   AdminController controller = new AdminController();   controller.Home();   Assert.IsTrue(Controller.Response.WasRedirected, "Should have been redirected"); } The problem with this was pretty obvious, Controller doesn’t have a Response etc set up. So along came attempt 2: [Test] public void AdminOnly_Home() {   AdminController controller = new AdminController();   PrepareController(controller);   controller.Home();   Assert.IsTrue(Controller.Response.WasRedirected, "Should have been redirected"); } Now the controller is set up with mock objects a

Validation

I have a model like so Product 1----* ProductVersion ProductVersion 1----* ProductEdition ProductVersion can been in one of two states: UnderDevelopment / Released ProductEdition has a DownloadUrl:string attribute which is only required if self.version.status = #Released The validation for ProductEdition works perfectly, I cannot leave the DownloadUrl blank if the ProductVersion has already been released. Unfortunately when I already have a number of ProductEdition instances with no DownloadUrl and then make my Productversion live the editions are not validated because they are not dirty. So I needed some way to ensure that when ProductVersion is validated all related ProductEdition instances are also validated. Step 01: Add a way to allow ProductVersion to identify other objects to be validated. In the business classes project I added the following interface. public interface IValidationExtender {   IEnumerable GetConstraintedObjects(); } My ProductVersion can do this IEnumerable

EcoRail

The whole idea of having a controller and a view is so that the view renders only exactly what it is given, and the controller is able to give it whatever data it likes from wherever it needs to obtain it. After working with ECO and Monorail for a while it has been a real pleasure, but I am starting to think that maybe exposing ECO objects directly to the view is not the right approach. If for example I put an Employee into the PropertyBag the view can easily display $Employee.Salary. This might not be a problem when you develop both the controllers and the view but in my case someone else will ultimately create the views. Do I really want them to be able to have access to this information? In addition, what if the view engine they use has a scripting language that is able to set values? Setting $Employee will merely set the PropertyBag["Employee"] value, but setting $Employee.Salary could see a certain view developer buying a new car next month. I am very tempted to chan