Is this 'layering' of my web-service correct? Can it be improved?
I am writing a Web Service to retrieve Invoice information from a database table. The specifics are as follows: I intend to give InvoiceAgentId as input and retrieve PayerId,PayerName, EffDate and InvoiceAgentId. Now, 1. In the InvoiceInfoSearch.asmx.cs file I have the WebMethod ... GetInvoiceInfo 2. I have the DTO objects InvoiceInfoRequest and InvoiceInfoResponse 3. I have the BusinessLayer manager class InvoiceSearchmanager 4. I have the DAL InvoiceInfoDAL
The web method in point #1 instantiates the InvoiceSearchManager class and calls the GetInvoiceInfo method in the manager by passing the InvoiceInfoRequest. Then the manager method instantiates InvoiceInfoDAL and calls the GetInvoiceInfo method in the DAL by passing the InvoiceInfoRequest. In the DAL method the InvoiceInfoResponse is instantiated and populated with retrieved record set and then propagated back to web method.
My questions: 1. Can both the InvoiceInfoRequest and InvoiceInfoResponse DTO classes have the exact same members? In my case PayerId,PayerName, EffDate and InvoiceAgentId. 2. Is this layering correct? Can it be bettered?
From a layering perspective your description looks good. You can have the same method names in the DAL and Business layers. The problem is with the tight coupling. As you are describing it your web layer instantiates the business layer which instantiates the DAL layer.
If this is the case how do you intend to unit test the business layer in isolation?
I would suggest you introduce a level of abstraction to the DAL and business layers (by having them implement interfaces). Then the business layer implementation could take the DAL interface as a constructor argument (constructor injection) instead of having it instantiate the DAL.
This level of abstraction will allow you to substitute the real DAL in the unit test by a mock object and test the business layer in isolation.
All the plumbing (instantiations) will be done at the web tier.
It's all a matter of taste, however my approach would be simpler:
Controller (eg your *.asmx.cs) -> Business Services -> DAL
Up to you. However, my architecture is borne out of what works (eg isn't rubbing against the grain) with spring and hibernate in the java world. I assume C# follows similar architectures.