This post is in continuance with the last post I had on WCSF. In this post I will briefly elaborate on various patterns in web development and the general terms used to help you understand WCSF in a comprehensive way.
The View Presenter Pattern
Asp.Net is a great web development platform that enables you to be productive from day one. However, careful understanding of patterns is needed in order to program better.
I have been myself part of many projects where the code behind page will run into many lines of code, embedding the business logic and database calls. A generic pattern I have seen with many code behind pages is that they have the code for interaction for the user events, code to interact with the domain/database data and present it to the end user by databind calls. Though for a small project this might not be an issue at all, but in a enterprise level application, this approach, will end up having complex code behind making it difficult to test and maintain. The other concern here would be that I would need to rewrite or copy this entire stuff should I need them in other module(s).
The solution here is to go for View-Presenter. Separate the responsibilities for the visual display and the event handling behavior into different classes, the view and the presenter. The view class (.aspx.cs page) manages the controls on the page, and it forwards events to a presenter class. Once the presenter class gets the events it is responsible for communicating with the Business Logic Layer and responding back with the data/behavior to the View.
In the View-Presenter pattern the view does not know about the Model. The interaction with the Model is completely a responsibility of the Presenter. This makes it easy to have a TDD with Mock Implementations.
Two Important Patterns for implementing View Presenter
You can implement the View-Presenter using Observer Pattern or Application Controller pattern. In the Observer Pattern the Presenter listens to the events from the model and updates the corresponding events. The reference implementation of WCSF uses Application Controller pattern, explained in the next topic
The Application Controller Pattern
In the Application Controller pattern all the views interact with a single object which takes care of the page flow and the screen navigation logic. The Controller can also interact with the Model and define the flow based on the state of the Model.
The better way to describe the issue would by showing a code snippet. Here we have a BankAccount object which tries to insert a debit amount
The issue with this approach here is the heavy dependency of DatabaseService class on SqlClient.The concerns here are
- We need to rewrite the source code for DatabaseService.Insert to change the dependency from SqlClient to some other provider. Yes, I know that for most us this is not a changing factor, but lets say the product needs to be shipped to a client who wants to implement the backend as MySQL ?
- The concrete implementation of the dependencies must be available at compile time.
- The DatabaseService class is difficult to test in isolation because it has a direct reference to SqlClient (therefore, you cannot replace the service implementations with mock implementations).
We want to decouple the dependencies here so that we can replace/update the dependencies with minimal affect to the consumer and also help in Testing using mock implementations. Dependency Injection comes to our help here. Here we have a Constructor Injection that will help us various implementations
Notice : I am having an inference of the Type of Database in use, this in order to build the appropriate collection syntax to pass inside the parameters. If the implementation used NHibernate or EFX any other ORM then this would not be needed. To demonstrate the concept this approach is simple.
Now that we have different implementations I can switch over to any provider neatly and efficiently and also test using Mock Object implementation of my choice.