Putting interfaces in their own project(s)
When I started using test-driven development and the model-view-controller pattern, I noticed a change in the way I broke up the projects in a typical solution. Well, I noticed several changes, but the one I’m going to talk about now is how the user stories started to become the API of my business logic. Because of the separation of the UI and the business logic that’s created by using the MVC pattern, my user interface has become a consumer of my business logic through this API. Writing code this way gives me the flexibility to use the same logic with a completely different UI.
That may not sound like the kind of things that comes in handy very often; however, it’s making my life much easier for the latest project I’m working on. I’m working on an ASP.Net website, but I also plan on creating a Visual Studio plug-in, so developers can access the website features without needing to leave their editor and open a new browser. I may also end up writing a system tray tool that works the same way. I haven’t decided if the plug-in will communicate with my application by a web service, remoting, or WCF. But whatever method it uses, I’ll just end up writing a small bit of wrapper code in it to communicate with my business logic through the user story API.
Normally, my solution file will start out with four projects in it. They are:
- MyLibrary (containing things like my data access layer)
- Domain (the application’s business logic)
- Application (the UI project)
- TestDomain (unit tests for the Domain project)
The MyLibrary and Domain projects each contain an Interfaces folder, and the files within them are in the MyLibrary.Interfaces and Domain.Interfaces namespaces. The Application project has references to both the MyLibrary and Domain projects. However, since I’m going to have additional projects that will be passing objects of the interface types into a web service (for this example), They will either need to include the complete MyLibrary and Domain assemblies, or I’ll need to move the interfaces into their own assemblies. In order to keep the installations for the new projects small, I’ll move the interfaces into their own projects. So, the solution will now look something like this:
- MyLibrary (containing things like my data access layer)
- MyLibrary.Interfaces (the public interfaces used within MyLibrary)
- Domain (the application’s business logic)
- Domain.Interfaces (the public interfaces used within Domain)
- Application (the UI project)
- Notifier (system tray notifier project)
- Plugin (Visual studio plugin project)
- WebService (used by the Notifier and Plugin projects to communicate with the Domain layer)
- TestDomain (unit tests for the Domain project)
The Application and TestDomain projects (along with the new Notifier and WebService projects) will now need references to the new *.Interfaces projects. However, the Notifier and Plugin will only need to have the small *.Interfaces assemblies included for the installation.