Is split of service interface layer and business logic layers worthwhile?

When developing service tier, you need to consider several non-functional aspects as well. In small or medium-sized companies or in enterprises the application are developed and supported for several years. For service layer it stands many times more. But the technologies are changing faster and your services need to provide functionality for all sorts of clients. During the time I found it is much better from maintenance point of view to separate implementation of Service Interface and Business Logic layers. As time flies and it is needed to change communication protocol, developers could create a new project and implement new Service Interface layer only.
What everything is Service Interface Layer? From my perspective they are all publicly exposed classes and internal helpers. They are service interface, Data Transfer Objects (DTO) and mappers. Usually Business Logic has exactly same interface as Service Interface layer, but it is not a rule. Let me implement WCF service with one method:

[ServiceContract(Namespace="http://Basho.Samples")]
public interface ICustomerService
{
    [OperationContract]
    GetCustomerResponse GetCustomer(GetCustomerRequest request);
}

public class CustomerService : ICustomerService
{
    private readonly ICustomerBl _customerBl;
    private readonly IMapper<CustomerModel, GetCustomerResponse> _mapper;

    public CustomerService(ICustomerBl customerBl, IMapper<CustomerModel, GetCustomerResponse> mapper)
    {
        if (customerBl == null)
            throw new ArgumentNullException("customerBl");
        if (mapper == null)
            throw new ArgumentNullException("mapper");

        _customerBl = customerBl;            
        _mapper = mapper;
    }

    public GetCustomerResponse GetCustomer(GetCustomerRequest request)
    {
        try
        {
            CustomerModel customer = _customerBl.GetCustomer(request.CustomerId);
            return _mapper.Map(customer);
        }
        catch (Exception ex)
        {
            ...
        }

        return BaseResponse.Failed;
    }
}

The Service Interface Layer includes very simple implementation of service class and definition of interface. There are 2 DTO declared, GetCustomerRequest and GetCustomerResponse, which are here for transferring data purpose. And one helper class converts model to DTO as IMapper<CustomerModel, GetCustomerReponse>. Business Logic object is injected through service constructor, together with mapper. The Service Interface layer can be extended with exception handling, logging, metrics and other infrastructure.
Now let me implement same service as REST using ASP.NET Web API framework:

public class CustomerController : ApiController
{
    private readonly ICustomerBl _customerBl;
    private readonly IMapper<CustomerModel, GetCustomerResponse> _mapper;

    public CustomerController(ICustomerBl customerBl, IMapper<CustomerModel, GetCustomerResponse> mapper)
    {
        if (customerBl == null)
            throw new ArgumentNullException("customerBl");
        if (mapper == null)
            throw new ArgumentNullException("mapper");

        _customerBl = customerBl;            
        _mapper = mapper;
    }

    public GetCustomerResponse GetCustomer(GetCustomerRequest request)
    {
        try
        {
            CustomerModel customer = _customerBl.GetCustomer(request.CustomerId);
            return _mapper.Map(customer);
        }
        catch (Exception ex)
        {
            ...
        }        

        return BaseResponse.Failed;
    }
}

You can see there is not major difference between these 2 implementations. You can easily support new communication protocol, without big effort. And this is beneficial for long-life service from my perspective.

That’s all, now go write some code.

Leave a Reply

Your email address will not be published. Required fields are marked *