Dependency Injection: ABP uses and provides a conventional DI infrastructure.
Since this class is an application service, it's conventionally registered to the DI
container as transient (created per request). It can simply inject any dependencies (such as the IRepository<Task> in this sample). Repository: ABP can create a default repository for each entity (such as IRepository<Task> in this example). The default repository has many useful methods such as the FirstOrDefault method used in this example. We can extend the default repository to suit our needs. Repositories abstract the DBMS and ORMs and simplify the data access logic. Authorization: ABP can check permissions declaratively. It prevents access to the UpdateTask method if the current user has no "update tasks" permission or is not logged in. ABP not only uses declarative attributes, but it also has additional ways in which you can authorize. Validation: ABP automatically checks if the input is null. It also validates all the properties of an input based on standard data annotation attributes and custom validation rules. If a request is not valid, it throws a proper validation exception and handles it in the client side. Audit Logging : User, browser, IP address, calling service, method, parameters, calling time, execution duration and some other information is automatically saved for each request based on conventions and configurations. Unit Of Work: In ABP, each application service method is assumed to be a unit of work by default. It automatically creates a connection and begins a transaction at the beginning of the method. If the method successfully completes without an exception, then the transaction is committed and the connection is disposed. Even if this method uses different repositories or methods, all of them will be atomic (transactional). All changes on entities are automatically saved when a transaction is committed. We don't even need to call the _repository.Update(task) method as shown above. Exception Handling: We almost never have to manually handle exceptions in ABP on a web application. All exceptions are automatically handled by default! If an exception occurs, ABP automatically logs it and returns a proper result to the client. For example, if this is an AJAX request, it returns a JSON object to the client indicating that an error occurred. It hides the actual exception from the client unless the exception is a UserFriendlyException, as used in this sample. It also understands and handles errors on the client side and show appropriate messages to the users. Logging: As you see, we can write logs using the Logger object defined in the base class. Log4Net is used by default, but it's changeable and configurable. Localization: Note that we used the 'L' method while throwing the exception? This way, it's automatically localized based on the current user's culture. See the localization document for more. Auto Mapping: In the last line, we map input using the MapTo method of ABP's IObjectMapper. properties to entity properties. It uses the AutoMapper library to perform the mapping. We can easily map properties from one object to another based on naming conventions. Dynamic API Layer: TaskAppService is a simple class, actually. We generally have to write a wrapper API Controller to expose methods to JavaScript clients, but ABP automatically does that on runtime. This way, we can use application service methods directly from clients. Dynamic JavaScript AJAX Proxy : ABP creates proxy methods that make calling application service methods as simple as calling JavaScript methods on the client.