Showing posts with label Software Architecture. Show all posts
Showing posts with label Software Architecture. Show all posts

Sunday, June 13, 2010

Prism is witchery

For my newest project, I wanted to use Prism to guide us writing a decoupled WPF-application. I started investigating it and was quickly amazed about the module-approach. In our former WinForms-project, we didn't used a framework to guide us building a nice architecture, but developed our own clsForms-class (at that time even with hungarian notation *awkward*) and used even IPC to communicate across process-boundaries.

I began writing the framework for the new project with heavy guidance of Prism (RegionManager, EventAggregator, DelegateCommands and CommandBehaviors). In the end, we had some modules building a master-detail view with database-access. This was the time when other coworkers started to complain that the architecture is way too complex for such a small application as it is today. We started to discuss how to simplify it and at the end we had a draw in our opinions: some people wanted to keep everything (me included *g*) and some wanted to strip it down to remove Prism, to abolish dependency injection and the IoC container Unity. Our boss had to decide it and spoke to us: "thou shalt remove Prism but keep DI for a better TDD").

The top-3 reasons why Prism is evil for us* are:
(*) i.e. not for me

3) Using the app.config for setting up the modules is error-prone and not type-safe.
I told them that we could do it in code also but somehow I got not heared :/

2) Debugging is too hard.
When you get an exception in a view which will be inserted into a region, you got this Prism-Exception telling you that there was a problem resolving this module for that region. I learned here that you cannot expect everyone to look at inner-exceptions (admittedly mostly at level >5)...

1) Top reason why Prism is evil: it is too intransparent how the regions get filled (witchery *hooo*).
What can I say? For sure, you have to look at the good documentation at their homepage to get the hang of it. Else it's witchery, yes.

So we burned it and removed it from our solution with 10+ modules and about 10,000 loc. We needed 5 hours to remove the lightweight Prism-sections completely and substitute it with our own RegionManager-approach (which is basically the same) and with our own DelegateCommand-approach (wich is basically the same) and without the help for commanding of Prism (we now use code-behind to execute the commands). Ah yes, and we copied the EventAggregator out of the Prism-sourcecode and use it now, because our approach would be basically the same...

Everyone feels better now that the evil is being distroyed.

What was the problem? We're using a whole bunch of new technologies and paradigms in this project (WPF is new to us, as Entity framework, WCF, Prism, TestDrivenDevelopment and dependency injection). This means a lot to learn and sooner or later, your retentiveness is exhausted. This meant to sacrifice a pawn, in this case it was Prism.

Wednesday, August 5, 2009

How to build a collection of Interfaces

Here’s the problem: we have some files and some devices which operate with signals. As a signal is one of our main objects, we want to return a collection of signals when opening a file or beginning a communication with a device:

But of course, we want to handle each signal the same, so a signal from an EDF-file should be from the same class as a signal from a device. We could define a signal-class in the Main-library like this:

But this constructs a circular reference. We could create a converter for each special signal and build a collection in the main-library of all signals:

Ouch – ugly. For every signal-type we need one converter. What happens when DeviceSignal changes? Hopefully, we update the corresponding DeviceSignalConverter... Here’s my solution:

We implement all interfaces a signal could be loaded / imported from in the main-signal-class and use generics to simulate a factory. A EDF-dll could have:


public interface ISignal {
int SamplesPerRecord { get; set; }
}

public class SignalReader where T : ISignal, new() {
public override ICollection GetSignals() {
List signals = new List();
var signal = new T();
signal.SamplesPerRecord = 3;
signals.Add(signal);
return signals;
}
}

The signal in the main-library implements that interface:


public class Signal : ISignal {
public int SamplesPerRecord { get; set; }
}

We can now call the SignalReader and it returns us a collection of signals we can use:


public ICollection GetSignals() {
SignalReader reader = new SignalReader();
return reader.GetSignals();
}

We can implement further signal-readers just by implementing the necessary interfaces into the main-signal-class. In fact, for each reader we created from Signal inherited classes implementing the interface the reader defines. With that construct, we can work without circular references and get a collection of objects we can work with.

Wednesday, June 10, 2009

What a wonderful world

Recently I read a lot about the M-V-VM pattern and I wanted to try it out. So I started small with a WPF-application implementing a listview showing some events related to sleep medicine. I’ve created a simple model with a collection of various data. This model is the data-provider for a ViewModel which is databind to this view:



So far, so good; worked pretty easy. I then read something about the graphical ability of WPF, which should be very bad in displaying a lot of graphical objects. Again, I wrote a sleep-medical-application, but this time showing some random biosignals with events:



The problem here was the very long signal build of thousands of Polyline-segments. And indeed, this brought WPF to its knees. You can’t show some signals with the pure use of WPF-technology. I instead used GDI+ inside of a Canvas-element for the signal and the VirtualCanvas-technique for the events (read here about it). With that I managed to preserve databinding on the modifiable objects (the events): you can move them around and change their duration by dragging their border.

In a second step, I combined the model of the ListView with that of the biosignals and injected it into its ViewModel. Of course, every ViewModel is being unittested – what a wonderful world:


Sunday, May 17, 2009

Thread-Threat

At work, I'm trying to get a software-feature faster by introducing multithreading. We import data from a device and convert it into our format. This is done sequentially at the moment, first importing, then converting. First tests have shown that we can get a benefit of about 30% if we do that in parallel. So I developed a wonderful producer-consumer-queue with a producer-thread and a consumer-thread which gets its data from the producer-thread. So far, so good: all unit-tests with that queue ran successfully.

However, as soon as I plugged that code into the import-conversion-piece to make it multithreaded, I got System.Runtime.InteropServices.COMExceptions with HRESULTs of -2147467259 (RPC_E_SERVERCALL_RETRYLATER, Unspecified error) or -2147417856 (RPC_E_SYS_CALL_FAILED, System call failed) - (here is a list with automation errors). These errors occured randomly on different parts of the code. But all code-parts had in common that they're calling a VB6-COM-object (well, it's a COMException - what should I expect...).

Some googling brought me similarities with Office-automation (see here and here for example). My picture about that problem became clearer and clearer and I sketched that diagram to understand it:


Thread A and B are accessing the same COM-object. This access is provided via a RCW (runtime callable wrapper). There is only one RCW for all accesses to that COM-object (read the great article series "Beyond (COM) Add Reference: Has Anyone Seen the Bridge?" of Sam Gentile for a deeper dive into COM-interop). This means multithreading and COM-interop is no fun.

What about protecting the access to that COM-interop with a lock? I designed a little construct so that I won't forget to protect any calls to that COM-interop:


The wrapper for the COM-interop, ThreadSafeComInterop, offers the COM-interop via a Lock-class. Each time you want to access the COM-object, you acquire the lock. With that, a Monitor enters the lock and exits it not until the lock is disposed. It's neat with the using-construct:

Using lock = _interop.Lock
' do something with lock.ComInterop
End Using

See that sequence-diagram for further information:


The provider creates the ThreadSafeComInterop by passing the COM-interop to the constructor. The recipient can call the Lock via the using-construct and access the COM-interop via lock.ComInterop. By creating the ThreadSafeComInteropLock, a Monitor.Enter is established on a static lock-object. When finished using the COM-object, the Lock is being disposed and Monitor.Exit is being called to allow other components to access the COM-object.

This sounds great and tests are showing that the exception-rate is degreasing from 10 tries - 9 exceptions to 10 tries - 1 exception. But unfortunately, this exception is one exception too much. Reading "Lessons Learned Automating Excel from .NET" finally convinced me to write the needed parts of the COM-component in .NET.

Friday, March 20, 2009

Mix09 and "The Guide"

Right now, Mix09 is on air. This is a Microsoft developer conference focusing on web development. I bet, you want to see some videos from here.

I recently finished The Application Architecture Guide 2.0. Now I can design every system from a mobile app up to a RIA :)

Wednesday, November 26, 2008

Book review "Essential Software Architecture"

Tomorrow I will finish Essential Software Architecture. Ian Gorton uses a real web-project all over the book and it fits surprisingly good in all chapters supporting the content by fabulous examples. Maybe the chapters were constructed around the project because the book itself has a way too much web-related content in my opinion. At the end of the book (actually 1/3 of it), there are chapters presenting one emerging new technology each. Of course MDA and SOA are on board. But what is really interesting is Aspect Oriented Architecture (AOP). My next book will handle SOA - maybe the one after SOA will be about AOP, we'll see :)

Wednesday, November 19, 2008

Book review "Effektive Software-Architekturen"

Once more, yesterday I finished a book. This time the afore mentioned "Effektive Software-Architekturen". Here, views are good explained - finally I got the difference between views and viewpoints :) This book has also lots of checklists and good advices which makes it a bit shallow. Next book I'm reading is Ian Gorton: Essential Software Architecture.

Here are a few links I want to check out: Buschmann et al 96: A system of patterns, Bass et al: Software architecture in practice, pacman03.pdf.

Tuesday, November 11, 2008

Book review "Handbuch der Software-Architektur"

I finished yesterday a book about software architecture: "Handbuch der Software-Architektur". It tries to cover all themes of architecture especially with a good comparison to a "real" building-architect. Unfortunately, it becomes very abstract and far away of reality to the end of the book. It's more like a study-book than a real hands-on one. So, don't read it ;)

Now I'm reading "Effektive Software-Architekturen". The introduction is very amusing with a comparison between the "Wasserfallmodell", "V-Modell" and agile methods (hier unbedingt lesen).