What are business actions? They are simple units of business logic implemented using the Action base class from the Vergosity Framework. They are just simple classes that follow a specific pattern. All of the business logic is performed in the PerformAction() method. Notice that the constructor takes in the target entity CodeSample. The entity value is contained in a field called _codeSample – which is decorated with a rule attribute EntityIsValid. This rule is evaluated when the action is executed. If any of the business rules and data validation rules fail, the PerformAction() method is not called or processed. You can supply the action with as many input items as you wish. This action takes the input parameters in the constructor – however, there isn’t anything preventing you from adding public properties to do the same.
This action has an output object, the IsUpdated boolean property. Since we are using classes for the business logic implementation, we are not limited to a single return or output item. We can have as many as we need. Using classes to implement business logic has a lot of benefits.
Most of the magic of the business action is implemented in the ActionBase or more so in the framework Action class. The following shows the base action class which is a generic. It contains the common or shared elements of the business action and inherits from the Vergosity Framework Action class which is abstract. This base class contains a ProviderBase class which coordinates calls to other business actions within the specified service.
Vergosity Framework :: Action Class
The Action class provides the structure or processing pipeline for the business logic implementation.
The action process is started by calling the Execute() method. This is the implementation of the Template Method pattern. There is a series of things that happen before and after the execution of the actual business logic. And as you can see from the diagram above, if you want to include any additional behavior – there are several events that you can hook into to add your own custom features.
If everything goes well, meaning that the user is authorized via permissions and no business rules or data validations have been evaluated false – the call to the ProcessAction() is made. This is where the actual business logic is implemented or what you define as the action to perform.
There is a lot more going on in the StartAction() and the FinishAction() method calls – but for now just understand that there is a pipeline of processing for the execution of a business action. If you use business actions to implement all of your business logic, you have a very consistently mechanism for managing the process. Adding new behavior or features globally (to all business actions/logic items) is very easy using the base classes.
How Business Actions Are Called
You might be wondering how business actions are called. They are simply initialized as any class would be and started by using the Execute() method. The following example is more advanced because it is using Dependency Injection – but the approach is the same:
1. Initialize the action and pass in the parameters to the constructor.
2. Execute the action.
3. Retrieve the return object of the action.
You do not have to use Dependency Injection, however, the sample application I’m using demonstrates an architecture that takes advantage of DI techniques. The DI container is resolving the ActionManager<T> – a generic class. This generic type is injected with a BusinessProvider instance that is injected with a one or more Repository items used for data operations. There is a lot of opportunity to remove dependencies from your application objects by using DI. What we see in the ActionManager<T>.Execute() method is the actual call to the business action’s Execute() method. Using DI allows for more extensibility of my implementation of business logic. I can control how my business logic is wrapped and called – without effecting the actual implementation of the business logic. .
Using a class-based approach to implement units of business logic has many benefits. The implementation is very consistent and maintainable. Extending or adding new behavior is much easier using the base classes and/or using depending injection. Since each action class is a specific unit of business logic – there is a lot of opportunity to perform unit testing and perhaps using a test-driven approach to the implementation of the business logic.
The Action part of the Vergosity Framework is even more powerful when you combine it with the power of the business and data validation rule engine. Decorating your target objects with rule attributes is simple and easy.