Skip to content
This repository was archived by the owner on Aug 18, 2021. It is now read-only.

Business Logic Separation

Gustavo Denis edited this page Oct 31, 2019 · 1 revision
Main > Key Concepts > Business Logic Separation
For the sake of productivity, the more the programming code is clear and legible, the better.

However, current technology platforms contain many components to be integrated and used and many aspects to consider beyond the (business) algorithm in question.

It is hard to treat those technology matters in a way that isolates them from the core logic being written.

Liquid seeks to do that as good as possible so as minimum and precise mentions to such technical capabilities are done in business code.

![High level primitives for business code.png](/.attachments/High%20level%20primitives%20for%20business%20code-d45a22fa-d796-430b-9650-9eab384d0f66.png =900x)

Take the following example showing how Liquid hides most of the complexity of connecting to and consuming messages from a queue of a message/event bus:

...

//Injects the MessageBus cartridge for Azure Service Bus
WorkBench.UseMessageBus<ServiceBus>();

...

[MessageBus("ESHOP")]
    public class OrderingWorker : LightWorker
    { 
        [Queue("order_to_ship")] 
        public void ShipOrder(OrderToShipMessage message)
        {
            ValidateInput(message);

            //Calls domain (business) logic
            var response = Factory<OrderService>().Ship(message.MapTo<OrderToShipViewModel>());

            Terminate(response);
        }

In this case, Liquid resembles the same programming model of REST Controllers for the logic that responds to bus messages and events.

This strategy is so then followed for all technology capabilities Liquid abstracts and pre-integrates.

Therefore, the business logic is principal in code written on top of Liquid, with concise calls to technical primitives.

In contrast to what Liquid provides, see the following excerpt from the code of .NET Core reference application:

...

private void RegisterEventBus(IServiceCollection services)
        {
            var subscriptionClientName = Configuration["SubscriptionClientName"];

            if (Configuration.GetValue<bool>("AzureServiceBusEnabled"))
            {
                services.AddSingleton<IEventBus, EventBusServiceBus>(sp =>
                {
                    var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
                    var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>();
                    var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
                    var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();

                    return new EventBusServiceBus(serviceBusPersisterConnection, logger,
                        eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope);
                });
            }

            ...

            RegisterEventBus(services);

            //create autofac based service provider
            var container = new ContainerBuilder();
            container.Populate(services);

            return new AutofacServiceProvider(container.Build());
}

...

 private void ConfigureEventBus(IApplicationBuilder app)

        {
            var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
            
            ...

            eventBus.Subscribe<OrderStatusChangedToShippedIntegrationEvent, OrderStatusChangedToShippedIntegrationEventHandler>();
        }

...

    public class OrderStatusChangedToShippedIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToShippedIntegrationEvent>
    {
        private readonly IHubContext<NotificationsHub> _hubContext;

        public OrderStatusChangedToShippedIntegrationEventHandler(IHubContext<NotificationsHub> hubContext)
        {
            _hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
        }

        public async Task Handle(OrderStatusChangedToShippedIntegrationEvent @event)
        {
        ... 
        }

There are many technical (platform specific) commands mixed with proportionally few application (business) ones: OrderStatusChangedToShippedIntegrationEvent and corresponding Handle().

In this case, it is very hard to understand, restructure and evolve the code due to both technical and business demands.

Clone this wiki locally