MongoDB Integration
MongoDB Integration
Do define a separated
MongoDbContextinterface and class for each module.
MongoDbContext Interface
Do define an interface for the
MongoDbContextthat inherits fromIAbpMongoDbContext.Do add a
ConnectionStringNameattribute to theMongoDbContextinterface.Do add
IMongoCollection<TEntity>properties to theMongoDbContextinterface 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
MongoDbContextfrom theAbpMongoDbContextclass.Do add a
ConnectionStringNameattribute to theMongoDbContextclass.Do implement the corresponding
interfacefor theMongoDbContextclass. 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
CollectionPrefixproperty to theDbContextclass. 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
CollectionPrefixvalue for a module to create unique collection names in a shared database.Abpcollection prefix is reserved for ABP core modules.
Collection Mapping
Do explicitly configure all aggregate roots by overriding the
CreateModelmethod of theMongoDbContext. Example:
protected override void CreateModel(IMongoModelBuilder modelBuilder)
{
base.CreateModel(modelBuilder);
modelBuilder.ConfigureIdentity();
}Do not configure model directly in the
CreateModelmethod. Instead, create an extension method for theIMongoModelBuilder. 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));
builder.Entity<IdentityUser>(b =>
{
b.CollectionName = AbpIdentityDbProperties.DbTablePrefix + "Users";
});
builder.Entity<IdentityRole>(b =>
{
b.CollectionName = AbpIdentityDbProperties.DbTablePrefix + "Roles";
});
}
}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
cancellationTokento the MongoDB Driver using theGetCancellationTokenhelper method. Example:
public async Task<IdentityUser> FindByNormalizedUserNameAsync(
string normalizedUserName,
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await (await GetMongoQueryableAsync())
.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
includeDetailsparameters for the repository implementation since MongoDB loads the aggregate root as a whole (including sub collections) by default.Do use the
GetMongoQueryableAsync()method to obtain anIQueryable<TEntity>to perform queries wherever possible. Because;GetMongoQueryableAsync()method automatically uses theApplyDataFiltersmethod 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
MongoDbContextto theIServiceCollectionusing theAddMongoDbContext<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.
Last updated