Gazel configures Routine to expose every public method to be a business service. A business service is a public method that you can call using HTTP.
public methods are directly exposed as business services.
Persistent Objects as Parameters
You can use a persistent object directly in your business methods. Gazel will automatically lookup for a record with given id. If record is not found, it will automatically throw
Therefore, with the above code, you ensured that district is either null or an existing record in database.
Method overloads are considered as one business service in service layer. If you create method overloads like below, then you will see only one business service with all of parameters.
If you don't send an
ownerCompany then the first overload will be called, if you fulfill all parameters, then the second overload will be called.
Overload selection is automatic, and Gazel will try to pass as many parameters as it can. Assume that you send
ownerCompany to above
AddBranch service. Then first overload matches only
name parameter, but second overload matches both of them. So invocation will be on the second one and
district parameter will be
If return type of overloads are not the same, the first overload will be a business service, but the second one will be ignored.
array parameters and return types
You can use
List class for both parameters and return types as long as type parameter
T for lists is a supported type.
Gazel does not support
Dictionary in service layer and it will not never support it. You can always create methods accepting or returning dictionary, but these methods will not be a business service. The reason behind this design decision is to favor strongly-typed classes. If you need a class that is not a persistent class for input or output, then you can make use of DTO structs as explained in the following sections.
Data Transfer Objects (DTOs)
Data transfer objects are supported in two different usages in mind;
- DTOs for parameters: Input DTOs
- DTOs for results: Output DTOs
As their names imply,
- You create an input DTO only to use in parameters of your business services
- You create an output DTO only to return custom data as a result of a business service
And DTOs exist only to transfer data. Because of this reason, Gazel uses
structs for DTOs.
To accept a complex data in service parameters you can make use of input DTOs.
Properties of input DTOs should be
internal and constructor of input DTOs should be
public. This convention implies that;
- This struct should not be used for results because no-one from outside will see its properties,
- This struct should be used for parameters because constructor is public and everyone can create an instance of this struct.
Constructor parameters of input DTOs are just like parameters of business services. You can use
- primitives and other value types,
- persistent classes,
- other input DTOs
as parameters of constructor.
Example usage of an input DTO in a business service would be as follows;
If you need to get a list of name/value pairs you can simply create an input DTO with
Value properties. And use list of this DTO in a business service.
To return custom data from business services you can make use of output DTOs.
Properties of output DTOs should be
public and constructor of output DTOs should be
internal. This convention implies that;
- This struct should be used for results because its properties are public and everyone can see them,
- This struct should not be used for parameters because its constructor is internal and only internal classes create instances of this struct.
Notice that above constructor gets an instance of
Branch class and assigns values by using this
Branch instance. This will help you to create an instance of this struct whenever you have an instance of a
Example usage of this output DTO in a business service would be as follows;
Hiding Public Methods and Properties
In some cases you might need to have a public method, but you might not want it to be exposed as a business service. In this kind of cases, you can mark a business service by adding an
Internal attribute on top of a
property like below;
For the above example;
InternalManagerclass and all of its members will be hidden in service layer.
PublicManager.InternalServicemethod will be hidden in service layer.
- The constructor will be hidden,
InternalPropertywill be hidden,
PublicPropertywill be available in service layer
You can think of this attribute as an additional access modifier to
protected internal access modifier which we sometimes refer as