Yesterday, during our .NET User Group event here in Berlin, I talked with a colleague about legacy systems resp. system that are going to be legacy systems in nearer future and why they go there. Reason for this talk was a company he worked for. They have a big old software system with big (and old) problems in the code. Everybody knows that, but nobody wants to change something. So this conversation yesterday inspired me to write this post.
First I like to explain, from my point of view, why software systems become legacy systems:
On the one hand, technologies appear and disappear. And sometimes we used that technology and build complex software system on it. But one day, these technologies are at the end of their life cycle and they have to make room for new stuff. At this time, our software becomes slightly a legacy system. Technologies are not longer supported by their vendors, programming languages are dying, communities begin to shrink. Here I am talking about things like VAX, COBOL, CORBA, BTX and maybe soon WS*. Time to become a more expensive professional…
On the other hand, we dig the graves of our software systems ourselves – day by day. That is, when we do not review our code, when we do not measure quality of code and architectures, when we are to lazy to write documentations and when we do not leave our code for a while to review it from a higher level. And, of course, when refactoring is only some kind of a theoretical concept. Other reasons are the skills of developers and there different levels of knowledge. Tight deadlines and hardcore cost reducing bosses are giving the rest.
In those cases, our software systems become bigger and more unstructured with the time. They “evolve” to monsters, where only the old experts know how to change or fix the system. New scenarios become impossible to implement. Imagine, you want to write a mobile app for your in-house solutions but there are no web services you can use to access data or to use business processes. Those business processes are implemented directly in the desktop application that queries the database with SQL commands right from GUI event handlers (just to paint the very extreme scenario). No chance to reuse these implementations as well as extend the system at all. The system becomes legacy. The worst scenario at the end? Software entropy.
Today, agile development processes try to embrace reviews and refactorings in order to keep the code clean, well structured and good smelling. Short iteration lengths in agile processes keep developers off writing big amounts of code that is hard to refactor at the end. Instead, smaller pieces of software are written by developers that can be refactored in the next iteration (e.g. if the design approach was not good enough or the first implementation is not flexible enough to meet future requirements). Nice theory so far. And it works, I know.
But back to the example of my colleague, what is often the terrifying reality.
In reality, there are so many experts and old gurus out there, living in their old domain, not able or willing to leave it and discover new things. I think, some of you know these old SQL-guy who says that O/R mapper are unnecessary and will provide no benefits. “I can write faster SQL faster and better directly in the code”, “Look at my cool and complex SQL query. Can you do something like that with your O/R mapper?” And my favorite: “SQL is stronger than LINQ!”. Those sentences should be well known for tech guys. Refactoring is a foreign word for those people and running systems are, of course, never touched. These guys have often the power to convince their bosses to change nothing because of the risks. Because they worked for years with them. Some kind of reality, or what do you think?
That all makes it hard to maintain, extend and improve old complex software systems. Everybody is hating the code, but nobody wants to or is allowed to change it. That is the situation my colleague is tired of.
So, after a few mind games, I suggested him a simple and small approach for what he could do. With this in his bag, he can go to responsible colleagues, key developers etc. to convince them how easy it can be to extend the system by using new/other technologies and without effecting existing code. He can take the first step to initiate changes.
So, what is the idea? The system we are talking about is implemented with AspNet WebForms and an underlying MSSQL database. Data is accessed via DataSet directly in the Asp code. There is no other architectural or abstraction layer. Data access, business logic and presentation logic is mixed up in one code base. Data access works typeless due to usage of DataSet. That makes it complicated to extend the application nor to test it. Testing can only be done with GUI testing tools like Selenium or manually. Unit tests are difficult/impossible to implement.
The database is only accessible from the AspNet application running on the same server. So desktop clients cannot access the database also if they running on a machine within the same network. And if it is somehow possible for the desktop application to access the data, the complete business logic has to be implemented in this client. Think about mobile apps. No chance. There is no service layer…
Since their application is very data driven, it would be a good start to expose the data, somehow. Maybe a service layer would be cool. So clients can access the data via this service layer. With a service layer we enable many types of clients to connect to the database. Mobile clients, too! And what, if we can access the data via strongly typed objects? Would be a big improvement, too. These changes are not a perfect solution at all, but a “first” step in the correct direction.
So here the steps to do. We use Microsoft Visual Studio 2013 Update 2 here. First, we do some preparations:
1. Create new empty AspNet web project in Visual Studio.
2. Add WebApi and WebApi OData packages via NuGet to the project.
3. Add new file Global.asax to the project and configure the WebApi in this file, especially the routes.
Now we make the database available to our project and so to our code:
4. Add new item of type “ADO.NET Entity Data Model” to the project. Right click on this new item and reverse engineer the existing database. With this action, the Entity Framework tooling will generate entity types for all tables from the database that are under reverse engineering. That is all to make the data available. We get strong typed entities here! The EF tooling will generate a context class, too. This class is the entry point to communicate with the database. Great, with a few clicks, we have the database available via strong typed objects that can be used everywhere in our code.
Finally we add some WebApi service controller to create the web services which will expose our data to the world:
5. Add new controller to the project via the context menu. In the scaffolding selection dialog we chose “WebApi 2 OData Controller with Actions; using Entity Framework”. In the next dialog we can define for which entity type the controller will be generated. So we can define controllers per entity type. Every entity type with a controller is accessible via a separate URL. Imagine you have products, customers and orders as entity types, you can create three controller. One for each type. So you can access the data via these URLs (for further information about OData please visit http://www.odata.org/ or http://msdn.microsoft.com/en-us/library/ff478141.aspx):
Now we have exposed some web services which can be used to access the data from the database. Further we have strong typed entities that can be used in the service implementations. And last but not least: we have OData active as data query protocol. All this with a few clicks only. Now we can begin to implement e.g. a Windows Phone app that uses the new services. We can now use any other technology to build new components and clients. Older implementation is not effected because we did not touch it anywhere.
I hope I could show that big software designs and architectures are not needed to start changing things. It must not be expensive or risky to bring you old systems to newer platforms resp. opens them for other clients.
For a detailed description of how to create an OData service layer visit this MSDN article: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/creating-an-odata-endpoint
Please contact me if you have any questions or comments! I would be happy if I can help you!