Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I be calling an AppService from another AppService?

Context

Currently I'm working in a Documents and Records Management System (DRMS?). Because of some technical limitations I need to store a "view" file and a "source" file (DOCX or XLSX). A view file is a PDF file for users to print, download and view for every day usage while a source file is the editable file. When users require to update a file, they will download the source, update it, and upload a new view file and the corresponding source file.

I'm not able, at this time, to implement XLSX viewers/editors and, due to the quantity of files, I cannot migrate to ODFs in order to use open source viewers available.

Right now I have two models like this:

public class Document {
    //Other fields
    public virtual List<DigitalFile> Files { get; set; }
}

public class DigitalFile {
    //Other fields
    public virtual Document FileOf { get; set; }
}

The Document model has all the "business" data while the DigitalFile model has data about the files themselves (path, url, type, etc.)

Each time a document is created it will have 1 view file (required) and it may have 1 source file (some documents may not be editable). From this you can know that when a document is created/updated at least 1 digital file will be created/updated as well.

Problem/Question

I will have a DocumentAppService to handle all the CRUD operations but here's where my doubt comes, should I be calling an AppService from another AppService? I mean, when a Document is created, should the Create method call another Create method in DigitalFileAppService? Or should it be better if DocumentAppService handled everything on its own?

Right now all the CRUD operation on DigitalFile are tied to the operations on Document, which is why I'm in doubt of implementing an AppService for the files.

like image 429
IvanGrasp Avatar asked Oct 09 '17 19:10

IvanGrasp


2 Answers

I don't suggest to call an application service from another service in the same domain. Application services are designed to be called from UI layer. It implements audit logging, authorization, validation... and they will not probably needed if you use a code in the same application layer.

An application service method is a public endpoint of your application. Calling an application service from another is like going out of your application and entering from a different point. You also probably don't want to change an application service method if another application service method's signature changes (because of a requirement change in UI).

My suggestion is to seperate the shared code into another class (probably a domain service) and use from both application services.

like image 93
hikalkan Avatar answered Sep 20 '22 13:09

hikalkan


Ideally, an AppService should not call another AppService.

An application service should map Data Transfer Objects (DTOs) to Domain Objects (entities), apply application logic and pass these to the respective Domain Manager(s) for persistence.

It is perfectly alright to inject multiple managers, especially if mappings are configured properly. Where possible, an application service should not need to depend on another application service.


Realistically, an application service may provide convenience (and speed due to fewer server calls) by accepting nested "secondary" DTOs. These DTOs may involve separate application logic.

One way to do this cleanly is to create internal methods in the dependency application service, e.g. CreateInternal for a Create method. The internal methods are not converted to the dynamic Web API methods and avoid overhead of authorization and validation by interceptors.

Additionally, the ABP framework offers the [RemoteService(IsEnabled = false)] attribute if you want to call these methods directly from an MVC Controller — so the methods need to be public.

like image 40
aaron Avatar answered Sep 19 '22 13:09

aaron