Bryan D recently started a new contract with a large company that was developing a rich client application with all the latest buzzword technologies: WCF, WPF, BDD, etc. He was brought on to clean up the code and help figure out why the middle tier wasn’t so “middle”. It actually lived in the UI.
The middle tier seemed pretty straight forward: it was a collection of classes that were designed to be exposed as webservices and then called by the UI. Each service class implemented an abstract Interface that had a pretty straightforward set of method.
public interface IFindCustomerService { ... snip ... IList<ICustomer> ExecuteFindCustomers(string surname); }
Many of the implementation classes, however had modal dialog window contained within. Figuring that to be the cause of the tight coupling between layers, Bryan ripped out the dialogs from the middle tier and watched with horror as the application crashed and burned.
The problem was that all of the methods on the service were returning null. Digging further Bryan learned that, although the methods appeared synchronous, they used asynchronous calls... and modal dialogs to hold everything together.
public class FindCustomerService : IFindCustomerService { private ProgressDialog progressDialog; ... snip ... public IList<ICustomer> ExecuteFindCustomers(string surname) { dataProxy.OnAsyncCompleted += OnFindCustomerCompleted; dataProxy.BeginFindCustomers(surname); progressDialog.ShowDialog(); // this call blocks ... return Customers; } private void OnFindCustomersCompleted(object sender, EventArgs e) { Customers = dataProxy.EndFindCustomers(); progressDialog.Close(); // ... until this call closes the dialog dataProxy.OnAsyncCompleted -= OnFindCustomersCompleted; } }
So, instead of the UI presenting the user with a "please wait..." dialog when a service was called, it relied on the service to display the dialog to the user. Needless to say, the code has since been substantially restructured...