Browse Source

Allow to get others collections in a mongodb repository easily

pull/272/head
Halil İbrahim Kalkan 8 years ago
parent
commit
759bcb1863
  1. 18
      src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
  2. 15
      src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContext.cs
  3. 17
      src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContextExtensions.cs
  4. 2
      src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs
  5. 7
      src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IAbpMongoDbContext.cs
  6. 12
      src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IMongoDatabaseProvider.cs
  7. 8
      src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IMongoDbContextProvider.cs
  8. 12
      src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbDatabaseApi.cs
  9. 31
      src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs
  10. 7
      test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoDb_Repository_Tests.cs
  11. 10
      test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/CityRepository.cs
  12. 6
      test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/ITestAppMongoDbContext.cs
  13. 9
      test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/TestAppMongoDbContext.cs

18
src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs

@ -13,17 +13,19 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
where TMongoDbContext : IAbpMongoDbContext
where TEntity : class, IEntity
{
public virtual string CollectionName => DatabaseProvider.DbContext.GetCollectionName<TEntity>();
public virtual string CollectionName => DbContext.GetCollectionName<TEntity>();
public virtual IMongoCollection<TEntity> Collection => Database.GetCollection<TEntity>(CollectionName);
public virtual IMongoCollection<TEntity> Collection => DbContext.Collection<TEntity>();
public virtual IMongoDatabase Database => DatabaseProvider.GetDatabase();
public virtual IMongoDatabase Database => DbContext.Database;
protected IMongoDatabaseProvider<TMongoDbContext> DatabaseProvider { get; }
public virtual TMongoDbContext DbContext => DbContextProvider.GetDbContext();
public MongoDbRepository(IMongoDatabaseProvider<TMongoDbContext> databaseProvider)
protected IMongoDbContextProvider<TMongoDbContext> DbContextProvider { get; }
public MongoDbRepository(IMongoDbContextProvider<TMongoDbContext> dbContextProvider)
{
DatabaseProvider = databaseProvider;
DbContextProvider = dbContextProvider;
}
public override TEntity Insert(TEntity entity, bool autoSave = false)
@ -85,8 +87,8 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
where TMongoDbContext : IAbpMongoDbContext
where TEntity : class, IEntity<TKey>
{
public MongoDbRepository(IMongoDatabaseProvider<TMongoDbContext> databaseProvider)
: base(databaseProvider)
public MongoDbRepository(IMongoDbContextProvider<TMongoDbContext> dbContextProvider)
: base(dbContextProvider)
{
}

15
src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContext.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using MongoDB.Driver;
namespace Volo.Abp.MongoDB
{
@ -8,10 +9,14 @@ namespace Volo.Abp.MongoDB
{
private static readonly MongoEntityMapping[] EmptyTypeList = new MongoEntityMapping[0];
public IMongoDatabase Database { get; private set; }
private readonly Lazy<Dictionary<Type, MongoEntityMapping>> _mappingsByType;
protected AbpMongoDbContext()
{
//TODO: Cache model/mappings
_mappingsByType = new Lazy<Dictionary<Type, MongoEntityMapping>>(() =>
{
return GetMappings().ToDictionary(m => m.EntityType);
@ -23,6 +28,11 @@ namespace Volo.Abp.MongoDB
return EmptyTypeList;
}
public virtual IMongoCollection<T> Collection<T>()
{
return Database.GetCollection<T>(GetCollectionName<T>());
}
public virtual string GetCollectionName<T>()
{
return GetMapping<T>().CollectionName;
@ -38,5 +48,10 @@ namespace Volo.Abp.MongoDB
return mapping;
}
public void InitializeDatabase(IMongoDatabase database)
{
Database = database;
}
}
}

17
src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContextExtensions.cs

@ -0,0 +1,17 @@
namespace Volo.Abp.MongoDB
{
public static class AbpMongoDbContextExtensions
{
public static AbpMongoDbContext ToAbpMongoDbContext(this IAbpMongoDbContext dbContext)
{
var abpMongoDbContext = dbContext as AbpMongoDbContext;
if (abpMongoDbContext == null)
{
throw new AbpException($"The type {dbContext.GetType().AssemblyQualifiedName} should be convertable to {typeof(AbpMongoDbContext).AssemblyQualifiedName}!");
}
return abpMongoDbContext;
}
}
}

2
src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs

@ -11,7 +11,7 @@ namespace Volo.Abp.MongoDB
{
public override void ConfigureServices(IServiceCollection services)
{
services.TryAddTransient(typeof(IMongoDatabaseProvider<>), typeof(UnitOfWorkMongoDatabaseProvider<>));
services.TryAddTransient(typeof(IMongoDbContextProvider<>), typeof(UnitOfWorkMongoDbContextProvider<>));
services.AddAssemblyOf<AbpMongoDbModule>();
}
}

7
src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IAbpMongoDbContext.cs

@ -1,11 +1,16 @@
using System.Collections.Generic;
using MongoDB.Driver;
namespace Volo.Abp.MongoDB
{
public interface IAbpMongoDbContext
{
IReadOnlyList<MongoEntityMapping> GetMappings();
IMongoDatabase Database { get; }
IMongoCollection<T> Collection<T>();
string GetCollectionName<T>();
IReadOnlyList<MongoEntityMapping> GetMappings(); //TODO: Consider to remove from the interface
}
}

12
src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IMongoDatabaseProvider.cs

@ -1,12 +0,0 @@
using MongoDB.Driver;
namespace Volo.Abp.MongoDB
{
public interface IMongoDatabaseProvider<TMongoDbContext>
where TMongoDbContext : IAbpMongoDbContext
{
TMongoDbContext DbContext { get; }
IMongoDatabase GetDatabase();
}
}

8
src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IMongoDbContextProvider.cs

@ -0,0 +1,8 @@
namespace Volo.Abp.MongoDB
{
public interface IMongoDbContextProvider<out TMongoDbContext>
where TMongoDbContext : IAbpMongoDbContext
{
TMongoDbContext GetDbContext();
}
}

12
src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbDatabaseApi.cs

@ -1,14 +1,12 @@
using MongoDB.Driver;
namespace Volo.Abp.Uow.MongoDB
namespace Volo.Abp.Uow.MongoDB
{
public class MongoDbDatabaseApi : IDatabaseApi
public class MongoDbDatabaseApi<TMongoDbContext> : IDatabaseApi
{
public IMongoDatabase Database { get; }
public TMongoDbContext DbContext { get; }
public MongoDbDatabaseApi(IMongoDatabase database)
public MongoDbDatabaseApi(TMongoDbContext dbContext)
{
Database = database;
DbContext = dbContext;
}
}
}

31
src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDatabaseProvider.cs → src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs

@ -1,28 +1,25 @@
using MongoDB.Driver;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver;
using Volo.Abp.Data;
using Volo.Abp.MongoDB;
namespace Volo.Abp.Uow.MongoDB
{
public class UnitOfWorkMongoDatabaseProvider<TMongoDbContext> : IMongoDatabaseProvider<TMongoDbContext>
public class UnitOfWorkMongoDbContextProvider<TMongoDbContext> : IMongoDbContextProvider<TMongoDbContext>
where TMongoDbContext : IAbpMongoDbContext
{
public TMongoDbContext DbContext { get; }
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IConnectionStringResolver _connectionStringResolver;
public UnitOfWorkMongoDatabaseProvider(
public UnitOfWorkMongoDbContextProvider(
IUnitOfWorkManager unitOfWorkManager,
IConnectionStringResolver connectionStringResolver,
TMongoDbContext dbContext)
IConnectionStringResolver connectionStringResolver)
{
_unitOfWorkManager = unitOfWorkManager;
_connectionStringResolver = connectionStringResolver;
DbContext = dbContext;
}
public IMongoDatabase GetDatabase()
public TMongoDbContext GetDbContext()
{
var unitOfWork = _unitOfWorkManager.Current;
if (unitOfWork == null)
@ -48,11 +45,19 @@ namespace Volo.Abp.Uow.MongoDB
//TODO: Create only single MongoDbClient per connection string in an application (extract MongoClientCache for example).
var databaseApi = unitOfWork.GetOrAddDatabaseApi(
dbContextKey,
() => new MongoDbDatabaseApi(
new MongoClient(connectionString).GetDatabase(databaseName)
));
() =>
{
var database = new MongoClient(connectionString).GetDatabase(databaseName);
return ((MongoDbDatabaseApi)databaseApi).Database;
var dbContext = unitOfWork.ServiceProvider.GetRequiredService<TMongoDbContext>();
var abpDbContext = unitOfWork.ServiceProvider.GetRequiredService<TMongoDbContext>().ToAbpMongoDbContext();
abpDbContext.InitializeDatabase(database);
return new MongoDbDatabaseApi<TMongoDbContext>(dbContext);
});
return ((MongoDbDatabaseApi<TMongoDbContext>)databaseApi).DbContext;
}
}
}

7
test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoDb_Repository_Tests.cs

@ -90,5 +90,12 @@ namespace Volo.Abp.MongoDB
city.ShouldNotBeNull();
city.Name.ShouldBe("Istanbul");
}
[Fact]
public async Task Should_Access_To_Other_Collections_In_Same_Context_In_A_Custom_Method()
{
var people = await _cityRepository.GetPeopleInTheCityAsync("London");
people.Count.ShouldBeGreaterThan(0);
}
}
}

10
test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/CityRepository.cs

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB;
using Volo.Abp.TestApp.Domain;
@ -10,8 +11,8 @@ namespace Volo.Abp.TestApp.MongoDb
{
public class CityRepository : MongoDbRepository<ITestAppMongoDbContext, City, Guid>, ICityRepository
{
public CityRepository(IMongoDatabaseProvider<ITestAppMongoDbContext> databaseProvider)
: base(databaseProvider)
public CityRepository(IMongoDbContextProvider<ITestAppMongoDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
@ -24,10 +25,7 @@ namespace Volo.Abp.TestApp.MongoDb
public async Task<List<Person>> GetPeopleInTheCityAsync(string cityName)
{
var city = await FindByNameAsync(cityName);
throw new NotImplementedException();
//return await DbContext.People.Where(p => p.CityId == city.Id).ToListAsync();
return await DbContext.People.AsQueryable().Where(p => p.CityId == city.Id).ToListAsync();
}
}
}

6
test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/ITestAppMongoDbContext.cs

@ -1,11 +1,15 @@
using Volo.Abp.Data;
using MongoDB.Driver;
using Volo.Abp.Data;
using Volo.Abp.MongoDB;
using Volo.Abp.TestApp.Domain;
namespace Volo.Abp.TestApp.MongoDb
{
[ConnectionStringName("TestApp")]
public interface ITestAppMongoDbContext : IAbpMongoDbContext
{
IMongoCollection<Person> People { get; }
IMongoCollection<City> Cities { get; }
}
}

9
test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/TestAppMongoDbContext.cs

@ -9,11 +9,14 @@ namespace Volo.Abp.TestApp.MongoDb
[ConnectionStringName("TestApp")]
public class TestAppMongoDbContext : AbpMongoDbContext, ITestAppMongoDbContext
{
public IMongoCollection<Person> People { get; set; }
//TODO: We can set collections automatically, lik EF Core
//TODO: We can get collection names conventionally, or by an attribute
public IMongoCollection<City> Cities { get; set; }
public IMongoCollection<Person> People => Collection<Person>();
//TODO: Default implementation should read mogo collections from the context!
public IMongoCollection<City> Cities => Collection<City>();
//TODO: Default implementation should read IMongoCollections from the context!
//GetMappings should send a context and we add to it. Rename to ConfigureMappings.
public override IReadOnlyList<MongoEntityMapping> GetMappings()

Loading…
Cancel
Save