Skip to main content

An ORM would have saved time...


I've just finished working on a WPF, a pretty standard inventory system for widgets & gadgets. A hierachurial structure to the data that lends its self to a tree-view structure - essentially each node has a parent-child relationship, where a node can have multiple child nodes and each node has a reference to it's parent. The app is a simple a CRUD application with some UI tweeks on how the data was to be displayed - visualising the modified nodes in the tree and hows these affected the parent node.

What made this interesting was the fact this wasn't a new app from the ground-up, it was literally only a new UI, the database was already established in a production environment and had been for over 5 years, what made this interesting was the client was providing the DAL & BLL for the application - we were abstracted away from the database. All queries for data are returned via strongly typed data tables and all commands (updates) are done via explicit methods on the BLL. To be honest these didn't really measure up to my idea of a business logic layer, to perform a 'business action' with the BLL required multiple calls - so when trying to hydrate data from the database we had to make multiple calls to the BLL just to get all the data required, none of the BLL calls were designed with any real business need, they were more a need to get data from the database.

Originally when we started the engagement we knew nothing about the DAL & BLL provided by the client. Our presumption was to use an ORM as part of the 2 tier architecture utilising MVVM with the ORM being used directly from the ViewModel to reduce the number of abstractions - I agree with Ayende's stance on the use of a repository abstraction in  applications is no longer providing any benefit. We still planned to follow this architecture after we found out using an ORM was not an option, but it became obvious we would have introduce another abstraction into the application because the BLL didn't do exactly what was expected.

We ended up with the following abstraction;

public interface IServiceAssemblies
{
    Assembly GetAssemblyHierarchyForPackage(Package package);

    IEnumerable<Package> GetUserFleet(User user);
    IEnumerable<Namespace> GetNamespaces();
    IEnumerable<Parameter> GetNamespaceParameters(int assemblyId, int namespaceId);
    IEnumerable<Country> GetCountries();
    IEnumerable<Language> GetLanguages();
    IEnumerable<ServiceRegion> GetServiceRegions();
    IEnumerable<Type> GetTypes(int parentTypeId);
    IEnumerable<DataCollectorAssembly> GetStandAloneDataCollectors();
    IEnumerable<Type> GetListOfEquipmentTypes();

    void Save(Assembly assembly, DeleteClipboard deleteClipboard, User user, ref IList<Assembly> savedAssemblies);
    void Create(CustomerAssembly assembly, User user, ref IList<Assembly> savedAssemblies);
    void Create(DataCollectorAssembly assembly, User user, ref IList<Assembly> savedAssemblies);
}

Now this really is an abstraction! - it's not some pointlessly introduced service or interface that just does pass-through method calling or to facilitate testing. It's there to allow the abstracting away all the concepts I'd normally expect an ORM to handle. Concerns such as:

  • Caching of entities,
  • Lazy loading of entities,
  • Change tracking of entities,
  • Mapping of entities to & from relational model.

The implementation of this interface is over 1000 lines of pure procedural code and you can see from the interface there is a clear division between the queries & the commands, put simply they represent CRUD methods by another name.

I would have preferred not to have written any of this code. Not only did we have to implement these concerns but we had to deal with a hierarchical relational model that used tables to store multiple different business entity types that required re-cursing the hierarchical structure to determine the entity type - WTF!


Comments

Popular posts from this blog

Showing a message box from a ViewModel in MVVM

I was doing a code review with a client last week for a WPF app using MVVM and they asked ' How can I show a message from the ViewModel? '. What follows is how I would (and have) solved the problem in the past. When I hear the words ' show a message... ' I instantly think you mean show a transient modal message box that requires the user input before continuing ' with something else ' - once the user has interacted with the message box it will disappear. The following solution only applies to this scenario. The first solution is the easiest but is very wrong from a separation perspective. It violates the ideas behind the Model-View-Controller pattern because it places View concerns inside the ViewModel - the ViewModel now knows about the type of the View and specifically it knows how to show a message box window: The second approach addresses this concern by introducing the idea of messaging\events between the ViewModel and the View. In the example below

Implementing a busy indicator using a visual overlay in MVVM

This is a technique we use at work to lock the UI whilst some long running process is happening - preventing the user clicking on stuff whilst it's retrieving or rendering data. Now we could have done this by launching a child dialog window but that feels rather out of date and clumsy, we wanted a more modern pattern similar to the way <div> overlays are done on the web. Imagine we have the following simple WPF app and when 'Click' is pressed a busy waiting overlay is shown for the duration entered into the text box. What I'm interested in here is not the actual UI element of the busy indicator but how I go about getting this to show & hide from when using MVVM. The actual UI elements are the standard Busy Indicator coming from the WPF Toolkit : The XAML behind this window is very simple, the important part is the ViewHost. As you can see the ViewHost uses a ContentPresenter element which is bound to the view model, IMainViewModel, it contains 3 child v

Custom AuthorizationHandler for SignalR Hubs

How to implement IAuthorizationRequirement for SignalR in Asp.Net Core v5.0 Been battling this for a couple of days, and eventually ended up raising an issue on Asp.Net Core gitHub  to find the answer. Wanting to do some custom authorization on a SignalR Hub when the client makes a connection (Hub is created) and when an endpoint (Hub method) is called:  I was assuming I could use the same Policy for both class & method attributes, but it ain't so - not because you can't, because you need the signatures to be different. Method implementation has a resource type of HubInnovationContext: I assumed class implementation would have a resource type of HubConnectionContext - client connects etc... This isn't the case, it's infact of type DefaultHttpContext . For me I don't even need that, it can be removed completely  from the inheritence signature and override implementation. Only other thing to note, and this could be a biggy, is the ordering of the statements in th