Browse Source

Allow to get others collections in a mongodb repository easily

pull/272/head
Halil İbrahim Kalkan 9 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 TMongoDbContext : IAbpMongoDbContext
where TEntity : class, IEntity 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) public override TEntity Insert(TEntity entity, bool autoSave = false)
@ -85,8 +87,8 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
where TMongoDbContext : IAbpMongoDbContext where TMongoDbContext : IAbpMongoDbContext
where TEntity : class, IEntity<TKey> where TEntity : class, IEntity<TKey>
{ {
public MongoDbRepository(IMongoDatabaseProvider<TMongoDbContext> databaseProvider) public MongoDbRepository(IMongoDbContextProvider<TMongoDbContext> dbContextProvider)
: base(databaseProvider) : base(dbContextProvider)
{ {
} }

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

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

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

@ -1,11 +1,16 @@
using System.Collections.Generic; using System.Collections.Generic;
using MongoDB.Driver;
namespace Volo.Abp.MongoDB namespace Volo.Abp.MongoDB
{ {
public interface IAbpMongoDbContext public interface IAbpMongoDbContext
{ {
IReadOnlyList<MongoEntityMapping> GetMappings(); IMongoDatabase Database { get; }
IMongoCollection<T> Collection<T>();
string GetCollectionName<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.Data;
using Volo.Abp.MongoDB; using Volo.Abp.MongoDB;
namespace Volo.Abp.Uow.MongoDB namespace Volo.Abp.Uow.MongoDB
{ {
public class UnitOfWorkMongoDatabaseProvider<TMongoDbContext> : IMongoDatabaseProvider<TMongoDbContext> public class UnitOfWorkMongoDbContextProvider<TMongoDbContext> : IMongoDbContextProvider<TMongoDbContext>
where TMongoDbContext : IAbpMongoDbContext where TMongoDbContext : IAbpMongoDbContext
{ {
public TMongoDbContext DbContext { get; }
private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IConnectionStringResolver _connectionStringResolver; private readonly IConnectionStringResolver _connectionStringResolver;
public UnitOfWorkMongoDatabaseProvider( public UnitOfWorkMongoDbContextProvider(
IUnitOfWorkManager unitOfWorkManager, IUnitOfWorkManager unitOfWorkManager,
IConnectionStringResolver connectionStringResolver, IConnectionStringResolver connectionStringResolver)
TMongoDbContext dbContext)
{ {
_unitOfWorkManager = unitOfWorkManager; _unitOfWorkManager = unitOfWorkManager;
_connectionStringResolver = connectionStringResolver; _connectionStringResolver = connectionStringResolver;
DbContext = dbContext;
} }
public IMongoDatabase GetDatabase() public TMongoDbContext GetDbContext()
{ {
var unitOfWork = _unitOfWorkManager.Current; var unitOfWork = _unitOfWorkManager.Current;
if (unitOfWork == null) 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). //TODO: Create only single MongoDbClient per connection string in an application (extract MongoClientCache for example).
var databaseApi = unitOfWork.GetOrAddDatabaseApi( var databaseApi = unitOfWork.GetOrAddDatabaseApi(
dbContextKey, 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.ShouldNotBeNull();
city.Name.ShouldBe("Istanbul"); 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.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using MongoDB.Driver; using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB; using Volo.Abp.MongoDB;
using Volo.Abp.TestApp.Domain; using Volo.Abp.TestApp.Domain;
@ -10,8 +11,8 @@ namespace Volo.Abp.TestApp.MongoDb
{ {
public class CityRepository : MongoDbRepository<ITestAppMongoDbContext, City, Guid>, ICityRepository public class CityRepository : MongoDbRepository<ITestAppMongoDbContext, City, Guid>, ICityRepository
{ {
public CityRepository(IMongoDatabaseProvider<ITestAppMongoDbContext> databaseProvider) public CityRepository(IMongoDbContextProvider<ITestAppMongoDbContext> dbContextProvider)
: base(databaseProvider) : base(dbContextProvider)
{ {
} }
@ -24,10 +25,7 @@ namespace Volo.Abp.TestApp.MongoDb
public async Task<List<Person>> GetPeopleInTheCityAsync(string cityName) public async Task<List<Person>> GetPeopleInTheCityAsync(string cityName)
{ {
var city = await FindByNameAsync(cityName); var city = await FindByNameAsync(cityName);
return await DbContext.People.AsQueryable().Where(p => p.CityId == city.Id).ToListAsync();
throw new NotImplementedException();
//return await DbContext.People.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.MongoDB;
using Volo.Abp.TestApp.Domain;
namespace Volo.Abp.TestApp.MongoDb namespace Volo.Abp.TestApp.MongoDb
{ {
[ConnectionStringName("TestApp")] [ConnectionStringName("TestApp")]
public interface ITestAppMongoDbContext : IAbpMongoDbContext 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")] [ConnectionStringName("TestApp")]
public class TestAppMongoDbContext : AbpMongoDbContext, ITestAppMongoDbContext 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. //GetMappings should send a context and we add to it. Rename to ConfigureMappings.
public override IReadOnlyList<MongoEntityMapping> GetMappings() public override IReadOnlyList<MongoEntityMapping> GetMappings()

Loading…
Cancel
Save