Versão
Idioma

MongoDB Integration

  • Do define a separated MongoDbContext interface and class for each module.

MongoDbContext Interface

  • Do define an interface for the MongoDbContext that inherits from IAbpMongoDbContext.
  • Do add a ConnectionStringName attribute to the MongoDbContext interface.
  • Do add IMongoCollection<TEntity> properties to the MongoDbContext interface only for the aggregate roots. Example:
[ConnectionStringName("AbpIdentity")]
public interface IAbpIdentityMongoDbContext : IAbpMongoDbContext
{
    IMongoCollection<IdentityUser> Users { get; }
    IMongoCollection<IdentityRole> Roles { get; }
}

MongoDbContext class

  • Do inherit the MongoDbContext from the AbpMongoDbContext class.
  • Do add a ConnectionStringName attribute to the MongoDbContext class.
  • Do implement the corresponding interface for the MongoDbContext class. Example:
[ConnectionStringName("AbpIdentity")]
public class AbpIdentityMongoDbContext : AbpMongoDbContext, IAbpIdentityMongoDbContext
{
    public IMongoCollection<IdentityUser> Users => Collection<IdentityUser>();
    public IMongoCollection<IdentityRole> Roles => Collection<IdentityRole>();

    //code omitted for brevity
}

Collection Prefix

  • Do add static CollectionPrefix property to the DbContext class. Set default value from a constant. Example:
public static string CollectionPrefix { get; set; } = AbpIdentityConsts.DefaultDbTablePrefix;

Used the same constant defined for the EF Core integration table prefix in this example.

  • Do always use a short CollectionPrefix value for a module to create unique collection names in a shared database. Abp collection prefix is reserved for ABP core modules.

Collection Mapping

  • Do explicitly configure all aggregate roots by overriding the CreateModel method of the MongoDbContext. Example:
protected override void CreateModel(IMongoModelBuilder modelBuilder)
{
    base.CreateModel(modelBuilder);

    modelBuilder.ConfigureIdentity(options =>
    {
        options.CollectionPrefix = CollectionPrefix;
    });
}
  • Do not configure model directly in the CreateModel method. Instead, create an extension method for the IMongoModelBuilder. Use ConfigureModuleName as the method name. Example:
public static class AbpIdentityMongoDbContextExtensions
{
    public static void ConfigureIdentity(
        this IMongoModelBuilder builder,
        Action<IdentityMongoModelBuilderConfigurationOptions> optionsAction = null)
    {
        Check.NotNull(builder, nameof(builder));

        var options = new IdentityMongoModelBuilderConfigurationOptions();

        optionsAction?.Invoke(options);

        builder.Entity<IdentityUser>(b =>
        {
            b.CollectionName = options.CollectionPrefix + "Users";
        });

        builder.Entity<IdentityRole>(b =>
        {
            b.CollectionName = options.CollectionPrefix + "Roles";
        });
    }
}
  • Do create a configuration options class by inheriting from the AbpMongoModelBuilderConfigurationOptions. Example:
public class IdentityMongoModelBuilderConfigurationOptions
    : AbpMongoModelBuilderConfigurationOptions
{
    public IdentityMongoModelBuilderConfigurationOptions()
        : base(AbpIdentityConsts.DefaultDbTablePrefix)
    {
    }
}

Repository Implementation

  • Do inherit the repository from the MongoDbRepository<TMongoDbContext, TEntity, TKey> class and implement the corresponding repository interface. Example:
public class MongoIdentityUserRepository
    : MongoDbRepository<IAbpIdentityMongoDbContext, IdentityUser, Guid>,
      IIdentityUserRepository
{
    public MongoIdentityUserRepository(
        IMongoDbContextProvider<IAbpIdentityMongoDbContext> dbContextProvider) 
        : base(dbContextProvider)
    {
    }
}
  • Do pass the cancellationToken to the MongoDB Driver using the GetCancellationToken helper method. Example:
public async Task<IdentityUser> FindByNormalizedUserNameAsync(
    string normalizedUserName, 
    bool includeDetails = true,
    CancellationToken cancellationToken = default)
{
    return await GetMongoQueryable()
        .FirstOrDefaultAsync(
            u => u.NormalizedUserName == normalizedUserName,
            GetCancellationToken(cancellationToken)
        );
}

GetCancellationToken fallbacks to the ICancellationTokenProvider.Token to obtain the cancellation token if it is not provided by the caller code.

  • Do ignore the includeDetails parameters for the repository implementation since MongoDB loads the aggregate root as a whole (including sub collections) by default.
  • Do use the GetMongoQueryable() method to obtain an IQueryable<TEntity> to perform queries wherever possible. Because;
    • GetMongoQueryable() method automatically uses the ApplyDataFilters method to filter the data based on the current data filters (like soft delete and multi-tenancy).
    • Using IQueryable<TEntity> makes the code as much as similar to the EF Core repository implementation and easy to write and read.
  • Do implement data filtering if it is not possible to use the GetMongoQueryable() method.

Module Class

  • Do define a module class for the MongoDB integration package.
  • Do add MongoDbContext to the IServiceCollection using the AddMongoDbContext<TMongoDbContext> method.
  • Do add implemented repositories to the options for the AddMongoDbContext<TMongoDbContext> method. Example:
[DependsOn(
    typeof(AbpIdentityDomainModule),
    typeof(AbpUsersMongoDbModule)
    )]
public class AbpIdentityMongoDbModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddMongoDbContext<AbpIdentityMongoDbContext>(options =>
        {
            options.AddRepository<IdentityUser, MongoIdentityUserRepository>();
            options.AddRepository<IdentityRole, MongoIdentityRoleRepository>();
        });
    }
}

Notice that this module class also calls the static BsonClassMap configuration method defined above.

Esta página foi útil?
Por favor, faça uma seleção.
Obrigado pelo seu valioso feedback!

Observe que, embora não possamos responder aos comentários, nossa equipe usará seus comentários para melhorar a experiência.

Neste documento
Mastering ABP Framework Book
Dominando a estrutura ABP

Este livro o ajudará a obter uma compreensão completa da estrutura e das técnicas modernas de desenvolvimento de aplicativos da web.