Posts

Showing posts with the label ECO

ECO docs progress

I'm currently in the process of migrating the QuickStart series from BDS over to VS and recreating the accompanying source code. There's quite a lot of information in those articles, I hadn't realised how much I had written! Well, the transcription is going quite well. So far I have made it as far as article number 5. This one is going a bit slower because it is also a translation from VCL .NET to WinForms.

MonoRail

I'm working on a new website for work. I've decided to use ECO for the business model due to how much time it saves me. I took a look at the new MVC ASP approach provided by Microsoft recently and was a bit disappointed. There were bugs in some pretty basic errors that would have been an annoyance to code around, and it just didn't feel "ready". So, I've decided to take another look at MonoRail. I'd already written an ECO implementation for MR in the past but I decided to start the implementation from scratch. This was mainly inspired by the new EcoSpaceManager in ECOIV for ASP .NET. Using an EcoSpaceManager you can easily utilise many instances of different types of EcoSpace in the same page. I decided I would do the same. Unlike the EcoSpaceManager I haven't gone for unique string values for identifying the EcoSpace instance I want. That approach is good in ASP .NET where you want to bind different components together to generate your HTML bu

Why I don't use ExternalID for URLs

An External ID consists of two parts, ! ClassID isn't really required for ECO controlled DB structures because there is always a root table containing the ObjectID + ClassID, but when you use ECO to map to an existing DB structure there needs to be a way to know that object 1234 needs to be fetched from the PERSON table. So, now that we know why the ExternalID consists of two parts on to why I don't use it (much). If I am writing a website with ECO and I use the ExternalID for my URL like so www.mysite.com/showarticle.aspx?id=23!1234 The number 23 is determined by looking for the class's index in the list of all classes in the model. This is the problem! If you change your model by adding a new class then your index may change from 23 to 24. Not a big problem for your application, but persistent links to that URL from other sites such as Google will no longer work. An ExternalID is just like an object's pointer address. When you restart your application that addre

Derived properties that you don't want cached

I'm rewriting a Win32 application using ECO. One of the things this application allows the user to do is to specify their preferred unit of measurement for height, distance, depth, weight, and speed. To achieve this I have an ECO class ApplicationSettings which is a singleton which identifies the units to use. I then have 2 properties for each value.... InternalLandingDistance DisplayLandingDistance The idea is that I should never expose Internal* properties in the GUI but display their corresponding Display* property instead. The Display* property will read/write the Internal* property and perform some kind of conversion on it. If I always store my values using the unit with the highest accuracy (Distance = feet, Depth = millimetres, Weight = Pounds, Speed = KPH) then I just need to convert them by the correct factor when reading/writing from the Display* properties. This isn't rocket science, obviously I can just implement these as reverse derived attributes right? The pr

RetrieveChanges(out ignoredChanges)

Here's another quick blog about a new ECO IV feature. I asked for this during development because I had a particular problem I had to solve. My new application has a class named "PlannedCall". When the user logs in they see a list of planned calls that are A: Active B: Not already actioned C: Assigned to the current user, or not assigned to anyone D: EarliestCallTime <= Today + 1 As time goes on there will be a lot of instances of this class in my DB, so obviously I want to use the OclPSHandle to select my objects otherwise I will end up with a whole load of objects in memory that I do not need. However, when another user actions the planned call the Actioned property becomes true. If I use an ExpressionHandle then this planned call would disappear from the presented list, but with OclPSHandle it will not. This is where the new feature comes in! When you call PersistenceService.RetrieveChanges a collection of DBChange will be sent to the client from the server. T

ECO IV

CodeGear are letting some people blog about features in the next release of Delphi (Highlander) before it has even been released. How cool is that? A lot less secrecy, what a great move! Sooooo. How about I spill some beans about ECO IV? Maybe I can find a thing or two to mention :-) I'll just throw together something unplanned, so expect a weird mixture of stuff in no logical order whatsoever! Well, first of all , you're going to get a whole load of source code. I mean *lots* of it! There's a new service called the ICacheContentService . Let's say you know for a fact that there is an object in the DB with the ECO_ID 1234 and it is a Customer. Instead of loading that object into the cache with an OclPS evaluation you can simply use this service to register it in the cache. I've found this really useful in an app I am writing where I use SQL to find customers matching a certain sales criteria. I then create an IObjectList of these customers by injecting the

More secure passwords

Storing a plain-text password in a DB leaves your system open to abuse from anybody with access to the tables (sys admin for example). Here is the technique I recently used. Instead of storing the password itself I store a hash of the password, and a random "salt" that was used to create the hash to make it less predictable. [UmlTaggedValue("Eco.Length", "255")] private string PasswordHash { get { ... } set { ... } } [UmlTaggedValue("Eco.AllowNULL", "True")] [UmlTaggedValue("Eco.Length", "40")] private string PasswordSalt { get { ... } set { ... } } As you can see I do not store the password, just a hash + salt, both of which are private. Here are the methods used to set the values of these properties. public void SetPassword(string newPassword) { if (newPassword == null) throw new ArgumentNullException("password"); if (newPassword.Length < 6) throw new

UndoBlocks, SyncServer, and multiple EcoSpaces

In an ECO app I am writing it is very important that updates by other users are identified as soon as possible. This is because there will be multiple users all selecting jobs to do from a predefined list, and it is not only possible but also very likely that more than one user will select the same job at the same time (the job at the top of the list). To implement this I chose to use the remote persistence feature of ECO and in particular its Sync Server feature. Every 5 seconds my client apps will contact the server and retrieve a list of updates made by other users, it will then apply those updates to the cache of its own EcoSpace. So when a user selects a job to do at the top of the list their app will stamp it as InProgress and update the DB, the job will then automatically disappear from the screens of all other users. As I like to use undo blocks in my app to allow the user to cancel changes (using my DirtyObjectCatcher component) it is highly likely that during these synchro

CapableObjects announced

There are exciting times ahead! The team that brought you ECO for Delphi are now a separate company named Capable Objects ( http://www.capableobjects.com ). ECO will still be part of the next release of Delphi, but according to the official statement ( http://dn.codegear.com/article/3673> ) and comments in the newsgroups it is quite obvious there will also be a version of ECO for Visual Studio! In the past the ECO guys released patches for ECO bugs, unfortunately it was not always possible to provide a patch. With the guys now being a separate company they are free to decide their own release schedules. Instead of having to wait for a Delphi update they can now release updates as often as they wish. Just like the good old BoldSoft days when we used to get an official update really quickly if ever a critical bug was found. Not only that, but it would also seem that they will be shipping source code too! But that's not all John! The guys at Capable Objects have asked me to wr

ECO JumpStart

I've been up quite late working out what I want to cover in the "ECO jump start" document. The trick is to start at a level where the user knows absolutely nothing, and end up where they know enough to decide whether or not they wish to spend some time learning how to use ECO or not. I think I should start off explaining why multi-tiered app development is a good idea; then I think I should go on to creating a package in a DLL; then onto creating a non-persistent WinForm app using that package; then make it persistent; and so on. My problem is that ECO just does so much! I'll paste what I have so far at the bottom of this blog entry to get any feedback. As the list progresses the subjects become more advanced and I am worried that the jump start might actually frighten people off by making them feel overwhelmed. Maybe I should just take it so far and then leave the more advanced items out? Maybe I should just include a section at the end of the document explainin

ECO book at last!

Hi all I have finally reached a point where I can dedicate a few hours each today to "something new" and have decided that the ECO book I have always wanted to write would be great fun. My first idea is to create 2 or 3 separate items: Title: ECO jump start This would be in paper / PDF format and would contain a set of exercises for a new user to follow in order to get started with ECO as quickly as possible. It would basically cover creating a simple model, prototyping using auto-forms, using the different handles, databinding, parent-child grids, creating/evolving the DB, OCL / code derived / reverse derived attributes, and stuff like that. Title: ECO API This would be an electronic format which would basically be a "Press F1" reference. Title: ECO book This would either be a paper/pdf format or, if possible, part of the ECO API document. It would be a technical overview of the framework + its services and abilities. I imagine it might be similar to my ECO Ser

ECO extensions 2.1 released

I have just released a minor update to ECO extensions. It contains a fix for a bug that would prevent the DirtyObjectCatcher from catching modified objects for MDI child forms.

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: 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. The signal facto

Onion, part 3

Image
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", &

Onion, part 3 (teaser)

Image
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.

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

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

OCL aliases

This is just a copy/paste of a reply I made in a newsgroup, but I think it is quite informative so here it is.... KEY Square brackets denote a class [Person] Rounded brackets denote a role (Pets) Let's say you have a Car class and a Garage class, an individual car is regularly serviced at a specific garage so you have the following association [Garage] (Garage) 1----0..* (ServicableCars) [Car] Car.allInstances->select(Garage.Code = '1234') The above OCL will fail because "Garage" is a class so the parser is expecting stuff like "allInstances". So you might think this should work Car.allInstances->select(self.Garage.Code = '1234') but it doesn't because "self" refers to the root object and not the object at the parsed node where it is specified. This is what aliases are for: {aliasname} + {pipe} Car.allInstances->select(currentCar | currentCar.Garage.Code = '1234') This was possible in Bold too (native wind

Roles

Image
What is a Customer? If you are some kind of business service provider then it will be a Company, if you are a window cleaner then it will be a Person, but if you are a travel agent it could be either. What about a Supplier? You could argue the same as for a Customer, but you could also argue that a Company/Person could be both a Supplier and a Customer. This is where Roles come in. A Supplier isn't something you are, it is something you do, you supply something; just as a Customer consumes something. I find that it is much better to enable "Things" to perform more than one action, it is rare that life is simple enough for everyone to perform only a single role in life. The typical solution to this is the Party/Role pattern. A good point to make here is that this is a pattern, not a set of classes intend for inheriting from! This means that when you have a Company (alias "Party") you should create a CompanyRole class and associate them, descending Custome

ECO is so fast!

I spent the day (March 2005) training someone how ECO works. Between 9:30 and 12:30 we went through the basics, how to create a model in a package (and why). We then covered the different component types, whilst making a simple client/server app. Between 13:45 and 17:00 we went on to Create a server application Convert the client to connect to the server instead of directly to the DB Make the client synchronise with the changes from the server Create a web service which connected to the server for persistence Create a website which connected to the server for persistence That's a lot of work to get done in 3.5 hours at the best of times, but when you are also explaining why everything is done the way it is then this is surely a reflection of just how quick it is to develop applications using ECO. Everything we did was adhoc. I had no idea what the trainee wanted to cover before he arrived so everything was written from scratch. I'm quite frankly surprised that we managed to