views:

1232

answers:

1

My question is more of an architectural nature, less involved with the actual implementation.

I have build an API based on WCF, but can't really decide on how to separate the PL from the BL. I have made my service thin, so that it holds only a minimum of implementation, something like:

public TagItemResponse TagItem(TagItemRequest request)
{
   return (new ItemTagRequestProcessor()).GetResponse(request);
}

Than of course the first question arises, in what layer do the RequestProcessors belong? I think it would be wrong to call them a facade, but at the same time, they have nothing to do with presentation. As for now, i decided that they nevertheless belong in the PL. The processor methods take my DTO's (DataContracts) as input, validate the request message (base class), authenticate (base class) and eventually return a single DTO response, like so:

protected override void Process(TagItemRequest request, TagItemResponse response, Host host)
{
    var profile = ProfileFacade.GetProfile(host, request.Profile);
    var item = ItemFacade.GetItemId(host, request.Item);
    var tags = new List<Tag>();

    foreach (var name in request.Tags)
    {
        var tag = TagFacade.GetTag(profile, name);
        ItemFacade.TagItem(item, tag);
        tags.Add(tag);
    }

    ItemFacade.UntagItem(item, tags);
}

Now I ask myself, why do i need the facade classes 1:1 related to my business objects. For example i have a HostFacade that acts as a layer between the hostDAO and the processors. It, however, holds very little logic, it merely handles the DAO calls.

public static Host GetHost(HostDTO dto)
{
   return HostDAO.GetHostByCredentials(dto.Username, dto.Password);
}

Question: I might as well merge the processors and the facades, right?

I've read many articles/books on the subject, but i still can't settle on the 'right' way to go and tend to chose a different approach every time i face the issue. I wonder if a right approach even exists.

I've found f.ex. the doFactory example, where they talked to the DAO classes right from within the service implementation. I don't really like that, as most ServiceContract methods share some logic, and thus lend themselves well for use with shared base classes.

I've also found other examples where only the facades are called from within the services, but that seems to work well only for very fine-grained messages. My messages are 'fat' and composite in order to reduce the number of calls to the service as much as possible. My extra processing layer seems the be my real problem.

Probably there is no single answer as to how to correctly layer a WCF service, but hopefully there are some of you out there with an opinion that will either conform my instincts or shed some new light on the subject for me.

Thanx!

Geoffrey

+1  A: 

First, I assume that by PL you mean presentation layer, not persistence layer?

When implementing a layered application design, the main question should always be: can I replace the implementation of a lower layer without impacting the implementation of the layer(s) above.

This is usually best illustrated by the persistence layer. If you switch from SQL Server 2008 to MySQL for example, the persistence layer changes (of course). But are changes in the business layer also necessary? For example, does the business layer catch SqlException instances that are only thrown by SqlClient? In a good design, the business layer needs no changes at all.

The same principle should apply to the separation between business layer and presentation layer.

In your example, I would say that the ItemTagRequestProcessor should not be in the presentation layer. First, it has nothing to do with presentation, second, the implementation of processing a request is not a concern for the presentation layer. Compare it with a web application, presenting a TagItemResponse to a client is the concern of the web (presentation) layer. Retrieving an instance of TagItemResponse is the concern of a layer below the presentation layer.

Deciding whether to have a facade between your business layer and persistence layer is difficult. I usually do not implement a facade because it adds an extra (usually unnecessary) layer of indirection. Besides, I do not see a problem in calling persistence layer methods directly from business layer methods. If only you take the same principle into account: can you change the persistence layer implementation without affecting the business layer implementation.

Kind regards,

Ronald Wildenberg

Ronald Wildenberg
@rwwilden Thanx for the extensive reply! I can relate to your advise, and see your point(s). The doFactory example kind of threw me off-balance, handling the message processing directly within the service.
WIS3GUY.NET