From bcb8f59e40c0de81e7ed6c70c0be69d9ef80b1ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 10 Apr 2018 18:00:56 +0300 Subject: [PATCH] Creating module development best practices document. --- docs/Module-Development-Best-Practices.md | 54 +++++++++++++++++++ .../Repositories/MongoDB/MongoDbRepository.cs | 2 + 2 files changed, 56 insertions(+) create mode 100644 docs/Module-Development-Best-Practices.md diff --git a/docs/Module-Development-Best-Practices.md b/docs/Module-Development-Best-Practices.md new file mode 100644 index 0000000000..097b00dee1 --- /dev/null +++ b/docs/Module-Development-Best-Practices.md @@ -0,0 +1,54 @@ +## Module Development + +### Introduction + +This document describes the best practices for who want to develop modules that satisfies the following specifications: + +* Develop the module that applies the **Domain Driven Design** patterns & best practices. +* Develop the module as DBMS and **ORM independent**. +* Develop the module that can be used as a remote service / **microservice** as well as can be integrated to a **monolithic** application. + +### Data Access Layer + +The module should be completely independent of any DBMS and and ORM. + +- **Do not** use `IQueryable` features in the application code (domain, application... layers) except the data access layer. +- **Do** create separated packages (projects/assemblies/libraries) for each ORM integration (like *Company.Module.EntityFrameworkCore* and *Company.Module.MongoDB*). +- **Do** always use the specifically created repository interface (like `IIdentityUserRepository`) from the application code (as developed specified below). **Do not** use generic repository interfaces (like `IRepository`). + +#### Repositories + +* **Do** define a repository interface (and create its corresponding implementations) for each aggregate root. + +For the example aggregate root: + +````C# +public class IdentityUser : AggregateRoot +{ + //... +} +```` + +Define the repository interface as below: + +````C# +public interface IIdentityUserRepository : IBasicRepository +{ + //... +} +```` + +* **Do** define repository interfaces in the **domain layer**. +* **Do not** inherit the repository interface from `IRepository` interfaces. Because it inherits `IQueryable` and the repository should not expose `IQueryable` to the application. +* **Do** inherit the repository interface from `IBasicRepository` (as normally) or a lower-featured interface, like `IReadOnlyRepository` (if it's needed). +* **Do not** define repositories for entities those are **not aggregate roots**. +* **Do** define all repository methods as **asynchronous**. +* **Do** add a `cancellationToken` parameter to every method of the repository. +* **Do** create a **synchronous extension** method for each asynchronous repository method. +* ... + +#### Integrations + +##### Entity Framework Core + +##### MongoDB \ No newline at end of file diff --git a/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs b/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs index 2385ab150c..461b24460c 100644 --- a/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs +++ b/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs @@ -12,6 +12,8 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Domain.Repositories.MongoDB { + //TODO: Use GetCancellationToken() method! + public class MongoDbRepository : RepositoryBase, IMongoDbRepository where TMongoDbContext : IAbpMongoDbContext where TEntity : class, IEntity