M-V-VM Building an ERP-system – part 4 of N – commanding

Skrevet - Monday, May 31st, 2010 kl. 20:20 | Kategori - * Coding, English posts.

After part 3, we are getting ready to tie things together and as many might know, WPF contains the really nice ICommand interface that implements well with buttons, menus and inputbindings (go .Net 4.0). Back when I started out with WPF I used a lot of standalone implementations of the ICommand interface. It made for very nicely encapsulated commands, but there were problems. I put them into ResourceDictionaries for sharing them between views, but soon I had an overwhelming number of them, and naming became a problem. Also, maintainability proved troublesome. Having scattered business-logic scattered out into all these little classes that I couldn’t use DI (Dependency Injection) on proved a maintenance nightmare and ResourceDictionaries proved brittle (magic strings, anyone?). Testability wasn’t all that great either, and most of the commands were mostly doing boxing and un-boxing and IoC (Inversion of Control) resolution.

So, while a definete improvement over the old eventhandlers of Windows Forms, I wasn’t totally convinced it was the perfect solution – and then I stumbled upon the M-V-VM pattern (thanks to Josh Smith). This proved an eye-opener for me – binding to commands was a really neat trick – and the most important? I had functionality for views together in one spot. ‘What can I do with Customers in this view…? Oh look 4 commands in the CustomersViewModel – guess I can do those 4…’ Testing is a lot easier and I get the added bonus of one-place boxing and un-boxing. Wait a minute… I use the same CanExecute across commands? Well, not exactly – I wouldn’t want to introduce some sort of inheritance hierachy for something as simple as ICommands – no, enter the RelayCommand (again – thanks Josh).

Now, it may seem that Josh Smith is a demi-god of M-V-VM – and he is, but I do not agree with him in everything he does. I have read his article on MSDN, and I disagree on some of the choices he takes, but we do really different things, so that is to be expected. But you get to be the judge at which approach fits you better.

public class RelayCommand:ICommand
{

private readonly Predicate<object> _canExecute;
private readonly Action<object> _execute;
public RelayCommand(Action<object> execute)
{
_execute = execute;

}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{

_execute = execute;
_canExecute = canExecute;

}
public void Execute(object parameter)
{

_execute(parameter);

}
public bool CanExecute(object parameter)
{

return _canExecute == null || _canExecute(parameter);

}
public event CanExecuteChanged
{

add
{
if(_canExecute != null)
CommandManager.RequerySuggested += value;

}
remove
{

if(_canExecute != null)
CommandManager.RequerySuggested -= value;

}

}

If I had to point at one single class that has made the largest impact on my coding style – this is it. It has a bit of the functional programming that I’m still a beginner at, but realizing the potential of every day. In the ERP-system I’m about to construct, I will have 2-3 implementations of the ICommand interface – one of them being the RelayCommand. It saves me a lot of boiler-plate code (at least 8 lines per command – and that adds up when you have hundreds of commands). And DRY! Many commands will in the CanExecute method simply figure out if a parameter is of the correct type – and for a Customer – it is usually whether it is a customer… so, the four commands can share the same Predicate. I know it may seem like small pickings, but it was one of the few places, refactorings couldn’t really touch in standalone commands.

So – in the implementations of the first ViewModels, you will see a lot of RelayCommand’ing.

In part 5, I’ll finally start looking at the actual implementations of the ViewModels.

About the series:
The solutions introduced here are not entry-level material. You should understand generics and basic patterns to fully utilize the material presented. The solution represents about 3 years of experience working with one ERP-solution. Some of the choices taken are heavily influenced from the large-scale solution and may seem overkill for the simple examples here, but the idea is to show the end-result of my experience and hopefully you as the reader will at least see a new way of doing things. The solution is built in .Net 4.0 with heavy use of WPF’s capabilities. Here you can find the source-code for the series. You are free to use this code for any purpose, but it is presented as-is with no guarantees. Enjoy!

M-V-VM Building an ERP-system – part 3 of N – the first ViewModels

Skrevet - Friday, May 28th, 2010 kl. 23:26 | Kategori - * Coding, English posts.

After part 2 – we now have a model to work from – and it is time to create the first ViewModel.

After some carefull consideration – I’ve chosen that we need a list of Customers where we can perform CRUD (Create, Read, Update, Delete), to make things a bit interesting, we want to have a paged view as we expect our customers to range in the thousands – so we have the basis for our first ViewModels interface (and a few helpers):

public interface ICustomersViewModel:IPagedViewModel<ICustomer>
{

ICustomerFilter CustomerFilter {get;}
ICustomerCommands CustomerCommands {get;}

}
public interface IPagedViewModel<TEntity>:INotifyPropertyChanged
{

IEnumerable<TEntity> PagedData {get;}
ICommand MoveFirst {get;}
ICommand MoveLast {get;}
ICommand MoveNext {get;}
ICommand MovePrevious {get;}
int CurrentPage {get; set;}
int PageSize {get;set;}
int NumberOfPages {get;}

}
public interface ICustomerFilter:IBaseFilter
{

string AccountNumberSearch {get;set;}
string CompanyNameSearch{get;set;}

}
public interface IBaseFilter:INotifyPropertyChanged
{

event Action FilterUpdated;

}
public interface ICustomerCommands
{

ICommand NewCustomer {get;}
ICommand EditCustomer {get;}
ICommand DeleteCustomer {get;}

}

It might seem a bit complex for a simple list, but remember this is the refactored version after several other ViewModels have been built, so DRY has been applied. A few notes:

Why a separate class for the Commands – and why don’t you use the ApplicationCommands?
To keep the code straightforward and keep responsibilities apart (SRP), I try to keep the Commands seperate from the logic driving the querying. The reason, I don’t use ApplicationCommands is that in .Net 4.0 I get bindable InputBindings which will allow me to avoid code-behind routines to relay keyboard shortcuts – and ApplicationCommands will force me to do write new code-behind to wire them up to my commands. I would rather assign keyboard shortcuts than have messy code-behind.

What’s up with the Filter – why not publish just the string property in the viewModel?
A valid point – my experience is that Filters change as the customer gets to know the product – so I’d rather change a small filter class (plus the repository) without having to change the ViewModel class. Basically, I’m applying a change-rate dividing logic here – things that change often are isolated. Also, I want to make it clear what the search property is all about – it is easier to explain that all the properties in the filter-class are for reducing the query and everything in the ViewModel has something to do with interacting with the query-result (here changing pages and so on).

Why an extra event on the filter – it already has INotifyPropertyChanged?
I want to be explicit about when to update the data in the list. I might want it to update less times than properties change – or might delay it (for users with rapid keystrokes there is no sense in loading the list 6 times within one second). Also, if I end up with ranges – e.g. dates, I might update both dates and only want one update (e.g. when one date is entered that will result in an invalid date range – I will change the other date to produce a valid range).

Next, we need a detail view to edit the customers:

public interface ICustomerDetailViewModel:IEntityViewModel<ICustomer>
{

string AccountNumber{get;set;}
string CompanyName{get;set;}

}
public interface IEntityViewModel<TEntity>:INotifyPropertyChanged
{

ICommand CancelChanges { get; }
string[] ValidationErrors { get; }
ICommand SaveChanges { get; }
void SetActionOnClose(Action action);
void SetEntity(TEntity entity);

}

Not many surprises here – we need to be able to edit the customers details, as well as designate whether we want to commit changes.

What is the SetActionOnClose method about?
This is a hook to handle removing the view. Remember that the ViewModel has no knowledge of the View on top of it – and has no idea where it is placed, so we need a way to tell the ViewModel what to do when it is time to close.

In Part 4, I’ll look at implementing commands.

About the series:
The solutions introduced here are not entry-level material. You should understand generics and basic patterns to fully utilize the material presented. The solution represents about 3 years of experience working with one ERP-solution. Some of the choices taken are heavily influenced from the large-scale solution and may seem overkill for the simple examples here, but the idea is to show the end-result of my experience and hopefully you as the reader will at least see a new way of doing things. The solution is built in .Net 4.0 with heavy use of WPF’s capabilities. Here you can find the source-code for the series. You are free to use this code for any purpose, but it is presented as-is with no guarantees. Enjoy!

M-V-VM Building an ERP-system – part 2 of N – the model implementation

Skrevet - Wednesday, May 26th, 2010 kl. 23:15 | Kategori - * Coding, English posts.

As discussed in part 1, we need to implement the model somehow. The solution-source code shows the refactored result. There are 3 major implementation details that I will touch here:

Validation
I chose a solution here that is a bit more basic than I like in a production system, but still very capable – and easy to expand into a separate class when needs expand. I quickly added a generic base-class to handle all the ‘plumbing’-code (DRY applied harshly here). Below is the result for validation:

public abstract class AggregateRoot<TAggregate> : IAggregateRoot
{

protected static IListt<ValidationRulet<TAggregate>> _validationRules = new Listt<ValidationRulet<TAggregate>>();

public virtual bool IsValid(out string[] errors)
{
errors = _validationRules.Where(rule => rule.IsBroken(this as TAggregate)).Select(rule => rule.BrokenMessage).ToArray();
return !errors.Any();

}

}

Basically, I use a ValidationRule class to encapsulate validation – these rules can be very simple, or very complex and are applied sequentially. This means that I can get a list of all the things that are wrong (very usefull in UI for complex types). I hate (and I really do!) long if-statements thrown together with loads of unreadable conditions. For very complex rules, I would use a composite rule that would break all the scenarios into manageable chunks. To keep things simple, I didn’t add an IValidationRule<TAggregate> interface which I normally would to handle the composite rules. I favour encapsulated validation ie. the objects are capable of validating themselves. It’s mostly a matter of religion – but I like to have things encapsulated.

Equality and Identity
Equality and Identity may be the same thing – and then again might not be. We have two basic scenarios in our simple application – objects can either be an aggregate root (thus having an Id) or they can be a ‘simple type’ with little concept of identity. For aggregates, I’ve used the Id to determine whether we are talking about the same order. I cannot rely on two instances of any given order to be sharing the same memory allocation (ie. reference equality) – so, I’ll have a fall-back plan. I use the Id to do this. This leaves a problem with transient orders (ie. orders that have not been assigned an Id yet). I’ll not address this here (if I had used GUIDs this would not have been a problem), but just accept that if equality is important – users are only allowed to new one order up at the time…

For ‘simple types’ – here the order lines – I don’t really care if they are equal, but to facilitate later performance-runs, I will use the state to determine if these are equal – also, this enforces the idea that order lines are expandable and are replaced rather than copied – so, all state is used to determine if they are equal.

Collections
I didn’t discuss a major design decision in part 1 – why did I use an IEnumerable instead of an IList in the IOrder interface? Because I don’t want developers using all of the IList interface without my say-so. I might decide that all orderlines added will trigger some side-effect – or if the order is billed, you can no longer add order lines etc. Now, this can be easily added later by adjusting the AddOrderLine method. If I had OrderLines.Add(..) scattered all over my code-base, this would be very hard. Also the problem around .Remove() (see Part 1 for an explanation), could introduce nasty side-effects if developers are not consistent in how they treat the collection. Basically, I’m telling my colleagues – “This is what you can do – everything else is out of the question.” Internally I use an IList for convinience. I don’t expect an order’s orderlines to be so large that it will matter performance-wise – so, an IList is chosen here.

Part 3 will focus on the first ViewModels.

About the series:
The solutions introduced here are not entry-level material. You should understand generics and basic patterns to fully utilize the material presented. The solution represents about 3 years of experience working with one ERP-solution. Some of the choices taken are heavily influenced from the large-scale solution and may seem overkill for the simple examples here, but the idea is to show the end-result of my experience and hopefully you as the reader will at least see a new way of doing things. The solution is built in .Net 4.0 with heavy use of WPF’s capabilities. Here you can find the source-code for the series. You are free to use this code for any purpose, but it is presented as-is with no guarantees. Enjoy!

M-V-VM Building an ERP-system – part 1 of N – the model design

Skrevet - Wednesday, May 26th, 2010 kl. 23:15 | Kategori - * Coding, English posts.

I’ve decided to post a series on how I would start out designing an ERP solution with focus on Model-View-ViewModel. To fully understand the reasoning, this first part mainly discusses the model in which I work. Many of the later choices should be clearer if you understand the reasoning behind it.

First of, there is no ‘one way’ to do M-V-VM – and how you use it, will determine, how (and if) you benefit from it. I design ERP-systems (Enterprise Resource Planning) which are typically rich on business-logic and have high demands for user-friendliness especially in dataentry screens. Thus, if I did UI-designing like I did back in the VBA-days, I would end up with a jumble of spaghetti-code with UI-concerns creeping into the cracks of my business-objects. So, the main focus for me is getting rid of all things not business in nature and isolating it in ViewModels. Also, the domain of ERP-systems is typically used by different clients – ie. webservices, smart-clients and EDI-interfaces and having to maintain each of these with the same business model is critical. Performance is another key-point as the system is so large that basically the entire organisation will use it – in differnet ways and in different areas – and I cannot allow one users actions to impact all others. Also, I use WPF as the front-end and WPF has a lot of functionality that lends well to M-V-VM.

To keep things simple, the domain I use in this series is much less complex, but will scale very well for very complex scenarios. We will have Customers, Orders and OrderLines as the main objects – the business model looks as follows:

public interface IAggregateRoot
{

long Id{get;}
bool IsValid(out string[] errors);
bool IsTransient{get;}

}
public interface ICustomer:IAggregateRoot
{

string AccountNumber{get;set;}
string CompanyName{get;set;}

}
public interface IOrder:IAggregateRoot
{

DateTime OrderDate{get;set;}
ICustomer Customer{get;set;}
IEnumerable OrderLines{get;}
void AddOrderLine(IOrderLine orderLine);
void ClearOrderLines();

}
public interface IOrderLine
{

decimal Quantity{get;}
string Description{get;}
decimal PriceEach{get;}

}

Okay, should be kinda simple, but there are a lot of design-choices already made. Below, I’ll outline some of the reasons behind them:

Why does IOrderLine not inherit from IAggregateRoot?
Order lines belong to an order – and must never be allowed to exist with-out an order. Also, there is no complex logic in an orderline – it could easily be a struct in essence. People at this point may be thinking “but… when it goes to the database, it should have an Id!” – I disagree. An Id would make sense if we are allowed to update the orderline outside the context of the order – I have effectively made sure that cannot happen (in the domain – the gloves are off if you have access to the database).
Building an ERP-system is all about keeping options limited to the ones that make sense business-wise. The simpler the domain – the simpler the maintainance.

Why are there no setters on IOrderLine – how will you ever correct an order line?
I won’t correct it. I’ll replace it. Basically, the orderline is treated as if it was a simple type eg. an integer. I could have an RemoveOrderLine method, in the IOrder interface, but it would not make sense here. If I were to do that, how would I know I was removing the correct one? There is no Id to tell me which one is which – and there is no logic telling me that I cannot have two identical order lines. I would have to make sure, I was referencing the correct orderline (in memory) before removing it – adding needless complexity. Also, when the user edits the order, I’ll update the orderlines in one fell swoop as I’ll show later.

Why does the ICustomer interface not have an IEnumerable of the Orders?
Because it does not need it (yet, anyways). If I want to find all orders for a specific customer, I could query orders instead of querying the customer. Again, simplicity in the model is key – and two-way connections is complexity (who will update the other – how do I make sure they are saved correctly… etc.). Avoiding deep object dependencies is also key – before you know of it, you’re loading half the database because you wanted this one customer…

Why use interfaces? Isn’t that needless complexity? How about YAGNI?
Yes, at this point, interfaces are overkill – I jumped the gun at this point (they will be needed later), but interfaces are much easier to discuss instead of jumbling around in implementations which may be littered with all kinds of implementation details.

Why the IAggregateRoot interface and the methods in it?
Basically the IAggregateRoot interface is mostly for my convinience. At this point it is not really needed, but I do not want to change the interfaces later on (the final solution is built…), so, there are a few methods that are a bit ahead of time. Also, adherring to DRY (Don’t Repeat Yourself) is one of the most important code practices in my book, so that will shine through in the solution.

In part 2, I’ll discuss the implementations of the above interfaces and the reasoning behind it.

About the series:
The solutions introduced here are not entry-level material. You should understand generics and basic patterns to fully utilize the material presented. The solution represents about 3 years of experience working with one ERP-solution. Some of the choices taken are heavily influenced from the large-scale solution and may seem overkill for the simple examples here, but the idea is to show the end-result of my experience and hopefully you as the reader will at least see a new way of doing things. The solution is built in .Net 4.0 with heavy use of WPF’s capabilities. Here you can find the source-code for the series. You are free to use this code for any purpose, but it is presented as-is with no guarantees. Enjoy!

Some thoughts on WPF and the Model-View-ViewModel pattern

Skrevet - Saturday, May 8th, 2010 kl. 20:33 | Kategori - * Coding, English posts.

Having started on the endeavour it is to create an ERP system (this time for real), I’ve put a lot of thought into the structure of the project. Having worked on our solution for transport for nearly 3 years has of course given me a lot of insights into what does not work, but also a lot of things that really works for me. Just to outline what I’ve tried during these three years:

CSLA – it sounded good when we started out – having all logic for persistence, validation etc. defined in base classes sounded too good to be true. It was. As the domain grew, it became impossible to follow what was happening. On top of this, there was a lot of backwards compatibility that was polluting the API. In the end we ended up discarding the idea – and going more light-weight.

Enter our first from-the-ground-up domain model with SubSonic as our ORM. All domain classes were encapsulated, handling all internal logic including UI-logic. Having only two developers, we constantly had problems doing things the right way – having odd work-arounds to get objects behaving correctly (no UI-updating when getting the object from the database was one of the major problems). We hired a guy to show us how it was done…

Enter our current solution: We use NHibernate for persistence, have repositories/factories create objects for us – separated all UI-logic out into ViewModels, started using Presentation models for semi-lazy loading. I’m quite happy with our current structure – although there are some mistakes that need to be refactored out. Some of the domain objects have too much responsibility and are way too heavy when loading.

So, why not just use the current structure for the ERP solution? Well, much of it is going in as-is. There is one major difference, though. The ERP-solution is going to run on WCF-services instead of a direct link to a database. This means that as much as I would like it, domain objects are not going to be loaded directly from the database, but rather from Data Transfer Objects (DTO). What we’re going to do is this:

For a common scenario, we need to list Orders and then be able to pick one and edit it:
1. We send a paged query for Orders satisfying our conditions to the WCF-service.
2. We show the DTO’s directly – all DTO’s are light-weight and only represent the data of the current entity (no journal, no vat-account etc. – we only have the Ids to find it later)
3. The user selects one order for editing – we use a factory (we call it entity-creator as we have a factory already) to convert the DTO into a full-fledged IOrder (the domain object with all the logic). During this, everything needed will be loaded – the Partner that should recieve the order, VAT-codes, Currency and so on.
4. We wrap the IOrder into a ViewModel that will give us a rich editing experience with nice combo-boxes, nice graphics and on-the-fly updates with totals and so on.
5. The user now makes his edits – the order is continually validated (it is responsible for this).
6. The valid IOrder is sent to the repository for saving – here it is converted into a DTO again and sent to the WCF service which again converts it into an IOrder and checks everything is still valid and is saved to the DB.
7. The list of Orders is updated to reflect the changes.

This may seem like a lot of steps for something this simple. We reached this model after a number of discussions and try-outs. This solution will offer some benefits:
* It is extremely performant – we only load enough data to enable the user to make decisions.
* It is extremely flexible – we can use scalar properties on the DTO that does not exist in the domain – we can even use views to populate it handing the calculation to the database server.
* We enable a rich UI when editing as the ViewModels will be very responsive and can show consequences before actually committing it.
* All functionality when it comes to business logic is portable – everyone can make use of the API as it exists far below the UI-components.
* Designed for testing. All components are very small and encapsulated. SRP was one of the major priorities when coming up with this model.

There is a few drawbacks, though:
* Complexity. It goes without saying that developers will need to keep a clear head as there will be up to 25 classes into play for an average Order view to work.
* The ViewModels will have a tendency to grow a lot.

ViewModels… well, it is my pain-point. All the ‘junk’-code seems to end up here… It is far nicer than bloaty code-behinds for sure, but it seems to me that some of the UI logic tends to be a lot of boxing and unboxing – scores of If’s and maybe’s. And of course, the master of spaghetti-code: drag and drop. I will try something ‘new’ here (as in: new for me). I’ll try to split the responsibilities into a few groups and dedicate a class to each.

First candidate is Drag and Drop – here the problem is: What to put in code-behind and what to put into DragAndDropHelperClassYetToBeNamed (DAD). I’ve learned that attaching event-listeners directly to the view is a bad idea. Instead the DAD will throw Actions, Functions and Delegates at the view, and let the view decide when to use which. This will allow me to re-use functionality for different events (like when double-clicking and left-clicking-while-doing-the-hokey-pokey should do the same) – one drawback is that the view will need to know enough of the domain, to do simple deciding.

Second candidate is ICommands – many commands need to be re-used anyway, so they might as well reside in reusable classes. Almost all commands will be relayed commands with Predicates and Actions. Almost all ViewMdodels will have a Commands-property where functionality available for key-presses, menus and buttons will reside.

ValueConverters are already not in the ViewModel as they need to be reused – and thus reside in ResourceDictionaries. This leaves showing data, doing UI-updates and delegating requests to the domain/repositories. This will have to do for now… Now to actually implement it… Don’t get me wrong, I think ViewModels are a fantastic idea – but they can become unwieldy if attention is not kept.

Visual Studio 2010 – first impressions

Skrevet - Sunday, April 18th, 2010 kl. 9:08 | Kategori - * Coding, English posts.

In a lot of ways, my employeer tends to be a first-mover when it comes to new versions of software. In that tradition, I decided to take Visual Studio 2010 and the .Net framework 4.0 for a spin.

Executive summary: Do… upgrade… now… at least if you do WPF in LOB applications.

I ended up converting all our projects to 2010 (albeit only one of them to .Net 4.0) – below I’ll outline the improvements that justified that in my case:

Performance – my impression on performance is that it has really paid off that MS decided to postpone launch pending performance problems. It runs a lot better on my system compared to VS2008. My system suffers from poor harddisk performance which lead to many IO-issues crashing 2008 – these issues are all gone (2 days of heavy refactoring without a single crash is a pretty good indicator). I use a lot of XAML – which was a pain in 2008 as simple changes in the editor could take up to a second to perform (a major issue when your typing speed is above 300 key-hits/minute. It is virtually painless now – the intellisense has been vastly improved and the editor feels snappy. RAM usage seems to have gone up – after a day of refactoring, I’m at about 700 mb for a solution with 15 assemblies loaded and ~17.000 lines of code and heavy use of XAML. I have nothing to compare to, as it was unlikely to have VS 2008 run long enough for it to go above 400 mb (roughly required a restart every 3-4 hours).

I upgraded R# within minutes – despite improvements, Visual Studio is still no where near in functionality when it comes to refactoring support. VS 2010 and R# combined makes for effortless typing – free-text search in type-search is a fantastic feature in complex solutions. R# seems a wee bit slower when it comes to context actions – but the jury is still out on that one. R# caused my only crash just after installing – it turns out that performing 8-9 refactorings via key-strokes almost instantaneously does not work (I forgot the actual combination and tried out the 10 I thought might be it…).

.Net 4.0 – lots of good stuff here – new controls (much missed DataGrid, DatePicker and Calendar) that actually look like the other controls (out goes the Frankensteins from WPF Toolkit) – and my absolute winner hands-down: Binding support in InputBindings – such an obvious feature, but finally it is here. Took away about 80% of my code-behinds ontop of ViewModels. And did I mention the new editor? Absolute goodness performance-wise.

Oh – and the icing on the cake: Fantastic multiple display support – I use three screens – and now I can have my solution/properties/errorlists on one screen, debugging on another and have my primary screen dedicated to code… it almost makes my eyes water. (Yes, I know that you could do virtually the same with floating windows in 2008, but for me it was inflexible, irritating and nitty-picky work to have it working – now it has full support for docking in all views).

A few things deduct though – the release of the Ribbon-tooling as a separate package… well, I’ll live. But why in the name of … did they not fix the SelectedDate-Binding bug of the DatePicker? I have yet to dig into the code of the controls, but it seems only the icing was fixed on the controls from the WPF Toolkit CTP.

So, in conclusion – VS 2010 seems all about improving that which was poor in VS 2008 making the platform a much more friction-free and mature workplace. In my book that pays off. I have yet to find a lot of new functionality (may be due to using R# on top), but I seem to be using more of the tooling now that it is less trouble to do so. The new-comers in .Net 4.0 with dynamics and such will have to wait for me to find a use for them – for me the new stuff is mainly corner-case functionality, but then, I’m not really missing a lot as it is.

Status på mine projekter i øjeblikket

Skrevet - Saturday, April 3rd, 2010 kl. 20:27 | Kategori - * Rants.

Det her er egentlig mest en chance for mig selv for at danne et overblik over mine igangværende projekter (så jeg kan grine af det om 10 år…).

På arbejde er der ild i 3 forskellige projekter med varierende formål. Hovedprioriteten er vores brancheløsning, som kører i drift hos den første kunde, og som snart vil begynde at vende fokus mod nye moduler og ny funktionalitet. Der har været en del udfordringer i forhold til at performance-optimere det. Dels har jeg truffet et par uheldige valg i forhold til domænets opbygning, som har gjort query’ing tungt og dels har jeg været udfordret med en kraftig udskiftning i projektstaben.

Den næst-højeste prioritet er vores online booking. Den kører nu i drift hos tre kunder – det er en forholdsvis simpel løsning, men har indtil videre vist stort potentiale. Fokus her er på at få lavet de sidste kundetilpasninger og generelle små-funktionaliteter som vil gøre livet lidt lettere for vores kunders kunder. Samtidig er der et par integrationsmæssige udfordringer, som ikke er 100% løst endnu.

Sidst, men bestemt ikke mindst, har vi startet et pilot-projekt, som skal vise om vi kan samarbejde med en kon-kollega. Vi venter os meget af samarbejdet – foreløbigt har vi investeret en 30-40 timer på samarbejdet fra hver deltager (hvoraf omkring halvdelen er gået med koordination, møder og afklaring af funktionalitet). Så, det er i sin spæde start, men hvis alt klapper, vil det være en kæmpe fordel for begge firmaer – der er nu engang stor forskel på at gå fra at have en til at have tre at sparre med. Heldigvis minder vores firmaer meget om hinanden i forhold til hvordan vi tænker den fælles løsning – selvom firmaerne iøvrigt er vidt forskelligt drevet. Bare vidensdelingen og kompetence-bytning vil være af enorm betydning.

For første gang i udviklingsafdelingens historie har vi haft en måned med overskud… stort hurra (især fra min stakkels chef…) for det. Det vil nok være en enlig svale et stykke tid endnu – jeg siger snart goddag til en ny kollega, som skal hjælpe mig med at få styr på især test-delen af vores brancheløsning. Så der vil gå en periode med nedsat produktivitet indtil han har fået en chance for at sætte sig ind i løsningen.

Rent privat har jeg et projekt kørende med en tidligere arbejdsgiver, som dog er lagt på is indtil de finder ud af hvorvidt de skal ISO-certificeres. Det er for mig en lille hyggeopgave, der skal give dem et IT-system som understøtter deres nye LEAN-strategi. Omfanget er indtil videre ukendt, men vi har satset efter de lavest hængende frugter på tilbudsgivningen.

En spændende tid venter… Mange tiltag, der kan blive både en dreng og en pige.

Adventures into the web of Silverlight

Skrevet - Friday, March 12th, 2010 kl. 22:14 | Kategori - * Coding, English posts.

My employer decided it was time to get our online booking solution up and running. So, I was put to work – having heard so much about Silverlight and RIA services, I decided to have a go at it. Having no experience with online programming besides simple html, I had to go with something that would smell a little like programming in WPF.

To give the judgement before letting the jury vote, I was not impressed. I certainly like the syntax (it’s pretty much like WPF), but RIA services didn’t really win me over. I tried various approaches – first with Entity Framework (re-creating the database-schema giving everything a primary auto-generated column), switching to NHibernate with huge difficulties – then back to Entity Framework with a few Include-attributes. Now, it was beginning to shape up – DomainDataSources and the RIA-services for filtering and serving up the data filtered and sorted/grouped… and then I lost control completely. Yes, XAML power is nice, but I found the DomainDataSource desperately wanting – especially with ComboBoxes (Async binding just blows up). Switching to AutoCompleteTextBoxes sort of remedied that, but the lack of control of when the loading happened just finally sent me packing. I tried reverting to skipping the DomainDataSource and controlling the RIA-service directly… that turned out poorly, having a cache, that I have to remember to clear and odd syntax gave me head-aches.

I don’t know, for me the RIA services is a nice project – it has promise, but it isn’t really production-ready for me. Being used to the fine-grained control, NHibernate gives me, the combination of EF and RIA just didn’t live up to my expectations. Also, having UI-logic (INotifyCollectionChanged et all) baked inside the DTO’s. Well, to make a long story short, it was the end of RIA services for me in this go. I then decided to go the more ‘hardcore’ WCF way – and switched Silverlight after reading the fine print… (how in the name of all that is sacred do you expect me to make LOB-applications without printing…) with an online XBAP (WPF).

And, now I’m back – three customers deployed today with their own individual graphical layout, one with a printed form. And best of all, I have all of the control at my fingertips again – I decided against a deployed WCF-service in virtual folders as the deadline was rapidly approaching and I had no idea how to do it. Instead, I went the albeit more old-fashioned way of Windows Services published via WCF. Fine grained control, SRP pretty much applied everywhere – full usage of a 2nd level cache thanks to NHibernate.

Of course, there are drawbacks (.Net 3.5sp1 is needed client-side, download size is huge compared to Silverlight and deployment is… considerable), but the most important criteria were met – our customers’ expectations and deadlines (one day ahead of schedule is a rarity in our line of business) were met in full (and in one case surpassed by a fair margin).

Performancetuning – what a b…

Skrevet - Tuesday, January 12th, 2010 kl. 9:55 | Kategori - * Coding, English posts.

We have gone through some major refactorings lately due to performance problems. And while our performance has drastically improved – we are now at a point where further optimizations will prove futile. The reasons are many – the time we spend on performance tuning is now approaching a diminishing return, complexity in code is approaching problematic levels thus increasing cost of maintenance to name a few. I would now much rather throw hardware at it until it goes away.

Interesting bugs also rear their ugly head – it turns out that running our developement on the newest of the newest in terms of hardware and software versions is problematic, since our test customer is running on an erhm… let us say technically challenged platform. We are using every tool in the shed in terms of query-optimization in NHibernate – and it turns out there is a corner-case where certain combinations will work on SQL server 2005 but not SQL server 2000. I’m working on testing it on a small test project to prove that it is not us, that are idiots. For those interested – our bug manifested using HQL, a sorted query on a class that has joined subclasses with collections that we wanted to use subselects on in a paged resultset – and no lazy-load (yeah, not the simplest of scenarios…). NHibernate tries an optimization that uses the function Row_Number() which only works on on 2005 and later, thus throwing an exception. And yes, we use the MSSQL2000 dialect option in NHibernate.

So, before we do any further optimization on their solution, I want them to change to at least a newer version of their database software and get some decent hardware to go along with it. Next step will be cleaning up their workstations (4+ year-old-installations of XP perform… uhm… interestingly) and maybe upgrading them with DirectX 10. The problem is that they really do not want to spend much on their IT-infrastructure as they are planning on outsourcing it next summer, but right now their employees are suffering. Originally the plan was that they would have outsourced it already – we made it clear in the beginning that this new software would be hardware-hungry, but as the saying goes – “No battleplan is worth anything once the battle has started”, so we will adapt and overcome.

Tilbage til undervisning

Skrevet - Saturday, October 31st, 2009 kl. 21:14 | Kategori - * Rants.

Så er mit første kursus vel overstået. Det var en fornøjelse at prøve at undervise igen. Alt taget i betragtning gik det også godt. Deltagerne var positivt stemte og havde bortset et par mindre ting omkring kursusmaterialet ikke det store at indvende.

Jeg var lidt nervøs før vi gik i gang – jeg havde kun mødt den ene af deltagerne og var i tvivl om niveauet, jeg skulle lægge for dagen. Det viste sig dog at jeg havde ramt tæt på bortset fra at vi nåede lidt længere end forventet. De får naturligvis en opdateret version af kursusmaterialet, når jeg har opdateret det med det ekstra.

Undervisningen blev en blanding af en hardcore-design session og så en gennemgående øvelse, hvor de fik lov at bygge en Outlook-klon. Ikke fordi det er nogen banebrydende øvelse – mange før mig har brugt netop Outlook som baggrund, men det gav mig en chance for at visualisere alle de ting i WPF, som hører hjemme i et crash-course. Jeg var samtidig lidt heldig med de deltagere jeg havde. De havde begge prøvet WinForms og Delphi, så det var rutinerede kræfter, som blot skulle omskoles til WPF.

De næste kurser bliver en udfordring dog – det her kursus ville jeg kunne holde stort set uden forberedelse. Næste gang bliver det med en eksempel-applikation, hvor abstraktionsniveauet kommer til at lægge langt højere og der skal arbejdes for at gøre det til en strømlinet oplevelse. Kursusmaterialet er godt og vel halvt færdigt – så det tegner til at alt nok skal lykkes.

Nu mangler jeg bare at få solgt kurserne til nogle flere…

« Previous Page« Forrige indlæg« Previous Page · Next Page »Næste indlæg »Next Page »