Monday, 19 December 2011

Enterprise Application Integration: Part 1

Warning! This post and and related code is something I began a while ago but did not get round to completing. Since starting this I have read up on EAI techniques and also on SOA. I now understand that while the examples here may be suitable for integrating two or three small applications, they would not scale for anything other than a very small business. However, as one of the primary functions of this blog is to record my learning process, I have decided to include it.

Click here to download the code from Codeplex. Please make sure you click on 'Code for Part 1. This example cannot be run using SQL Server Express, it must be run on SQL Server. Please run the script in the SQL Scripts solution folder to create the required databases.

The solution contains the Client Data System from previous posts, and also the new Accounts System, which integrates with it. Both systems have an added layer: the Remote Facade layer, which provides a WCF wrapper around the Application Services. The UI then calls these WCF services.

This example demonstrates integration at three levels: at the UI level, the Domain level, and the Data level. Each of these forms of integration has its own motivations and features.

Integration at the UI Level

The Accounts System UI layer has references to both the Accounts WCF services Client Data System WCF services. The Client/Index page displays a list of clients, and to populate this, the Client controller has uses the Client Data System's WCF services to return the list of clients. There is no contact with the Account System's WCF services or domain at all.

Integration at the Data Level

From the client index screen, the user can click the 'Accounts' link for a particular client and this will display a list of accounts associated with that client. There is a business requirement that each account must be associated with a particular site, and the list of accounts lists the relevant site along side each account. The account record only has the ID of the site, but the list has to display the first line of the address. One way to do this would be to get the list of accounts from the Accounts System, and then for each record, call the Client Data System to get the site. However, this would result in n+1 database calls, and would therefore perform very badly. Another option would be for the UI to get the list of accounts, and then when it has all the site ID's, it could get all the sites in one go, and then join them in the UI controller. However, this would push too much code into the controller. (This could however be done by a service composition or possibly a task service. I will cover these in later posts.)

The method that has been adopted in this code is at the data level. A copy of the site entity exists in the domain (only with get/set properties - no logic), and also a mapping file that points to the Client Data System's database. The site entity in the Accounts System is read only - any edits to sites should be done though the Client Data System's services. This way, a query to return a collection of accounts can join to the sites.

Integration at the Domain Level

There is a business requirement that only established client can have accounts. Currently, an established client is on that has been a client for at least three months, but this is a possible area of change, so the logic must remain in the client entity in the Client Data System. When the validation logic in Accounts System needs to check if the client is established, it needs to use the services of the Client Data System so it can access the business logic in the domain to verify that the client is established. However, the domain cannot directly consume the Client Data System's as this would break the rule that the domain cannot have any dependencies. Instead, it consumes it though an interface. Another layer, the 'Integration Layer' contains the implementation of this gateway to make the service call, and this is injected in by the Application Layer. This is an example of the Gateway Pattern.

Another possibility would be for a service composition to use the Client Data Service to check the client's established status, and if it is established, it will then call the Accounts Service. This will be covered in a later post.