Skip to content
ahanusa edited this page Oct 13, 2015 · 35 revisions

The ServiceCommand is the actor responsible for orchestrating initialization logic, validation/business rule execution, and data proxy invocation. Service Commands inherit from Command and implement ICommand, and are returned by the public methods of service base.

ServiceCommand is meant to serve as an easy way to deliver custom command functionality from your service implementations without the hassle of having to create your own command implementations. However, if you don't find ServiceCommand to be flexible enough, you can also create your own commands that inherit from Peasy.Core.Command or alternatively, implement Peasy.Core.ICommand;

The service command offers many contructor overloads, each requiring different variations of arguments of type Func and Action. This functional design pattern is used to support thread-safety.

For example, many times you will not need initialization logic or business rules to execute before executing logic or interacting with data proxies. In this scenario, you can create a new ServiceCommand specifying methods to execute synchronously and asynchronously.

A simple example:

public ICommand<InventoryItem> GetByProductCommand(long productID)
{
    var proxy = DataProxy as IInventoryItemDataProxy;
    return new ServiceCommand<InventoryItem>
    (
        executeMethod: () => proxy.GetByProduct(productID),
        executeAsyncMethod: () => proxy.GetByProductAsync(productID)
    );
}

In this example, we expose the GetByProductCommand method that returns ICommand<InventoryItem>. Within this method, we instantiate a new ServiceCommand (ServiceCommand<InventoryItem>) which states that the result from both a synchronous and asynchronous execution will return an instance of an inventory item.

Note that in this example, we chose the constructor overload that only accepts our execution methods, as we don't require any initialization logic or validation of any validation/business rules in our execution pipeline.

A busy example

public ICommand<OrderItem> SubmitCommand(long orderItemID)
{
    var proxy = DataProxy as IOrderItemDataProxy;
    return new ServiceCommand<OrderItem>
    (
        executeMethod: () => proxy.Submit(orderItemID, DateTime.Now),
        executeAsyncMethod: () => proxy.SubmitAsync(orderItemID, DateTime.Now),
        getBusinessRulesMethod: () => GetBusinessRulesForSubmit(orderItemID),
        getBusinessRulesAsyncMethod: () => GetBusinessRulesForSubmitAsync(orderItemID)
    );
}

private IEnumerable<IRule> GetBusinessRulesForSubmit(long orderItemID)
{
    var orderItem = DataProxy.GetByID(orderItemID);
    yield return new CanSubmitOrderItemRule(orderItem);
}

private async Task<IEnumerable<IRule>> GetBusinessRulesForSubmitAsync(long orderItemID)
{
    var orderItem = await DataProxy.GetByIDAsync(orderItemID);
    return new[] { new CanSubmitOrderItemRule(orderItem) };
}

In this example, we create an instance of ServiceCommand, but this time we specify business rule methods in addition to our execution methods. Here we have written business methods and pass them in to the constructor of ServiceBase.

Clone this wiki locally