mirror of https://github.com/abpframework/abp.git
43 changed files with 724 additions and 171 deletions
@ -0,0 +1,43 @@ |
|||
using System; |
|||
using AbpDesk.Blogging; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Uow; |
|||
using Volo.DependencyInjection; |
|||
|
|||
namespace AbpDesk.ConsoleDemo |
|||
{ |
|||
public class BlogPostLister : ITransientDependency |
|||
{ |
|||
private readonly IQueryableRepository<BlogPost, string> _blogPostRepository; //TODO: Should not be needed to string
|
|||
private readonly IUnitOfWorkManager _unitOfWorkManager; |
|||
|
|||
public BlogPostLister(IQueryableRepository<BlogPost, string> blogPostRepository, IUnitOfWorkManager unitOfWorkManager) |
|||
{ |
|||
_blogPostRepository = blogPostRepository; |
|||
_unitOfWorkManager = unitOfWorkManager; |
|||
} |
|||
|
|||
public void List() |
|||
{ |
|||
Console.WriteLine(); |
|||
Console.WriteLine("List of blog posts:"); |
|||
|
|||
using (var unitOfWork = _unitOfWorkManager.Begin()) |
|||
{ |
|||
//_blogPostRepository.Insert(new BlogPost("Hello World 3!", "Hello World 3......"));
|
|||
|
|||
foreach (var blogPost in _blogPostRepository) |
|||
{ |
|||
Console.WriteLine("# " + blogPost); |
|||
|
|||
foreach (var comment in blogPost.Comments) |
|||
{ |
|||
Console.WriteLine(" - " + comment); |
|||
} |
|||
} |
|||
|
|||
unitOfWork.Complete(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,5 +1,6 @@ |
|||
{ |
|||
"ConnectionStrings": { |
|||
"Default": "Server=localhost;Database=AbpDesk;Trusted_Connection=True;" |
|||
"Default": "Server=localhost;Database=AbpDesk;Trusted_Connection=True;", |
|||
"AbpDeskMongoBlog": "mongodb://127.0.0.1:27017|AbpDeskBlog" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup> |
|||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> |
|||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> |
|||
</PropertyGroup> |
|||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" /> |
|||
<PropertyGroup Label="Globals"> |
|||
<ProjectGuid>63244dc7-34be-44e1-bf6f-f2672e59af36</ProjectGuid> |
|||
<RootNamespace> |
|||
</RootNamespace> |
|||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> |
|||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> |
|||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> |
|||
</PropertyGroup> |
|||
<PropertyGroup> |
|||
<SchemaVersion>2.0</SchemaVersion> |
|||
</PropertyGroup> |
|||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> |
|||
</Project> |
|||
@ -0,0 +1,20 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.MongoDB; |
|||
|
|||
namespace AbpDesk.Blogging |
|||
{ |
|||
[DependsOn(typeof(AbpMongoDbModule))] |
|||
public class AbpDeskMongoBlogModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.AddMongoDbContext<AbpDeskMongoDbContext>(options => |
|||
{ |
|||
options.WithDefaultRepositories(); |
|||
}); |
|||
|
|||
services.AddAssemblyOf<AbpDeskMongoBlogModule>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.MongoDB; |
|||
|
|||
namespace AbpDesk.Blogging |
|||
{ |
|||
[ConnectionStringName(ConnectionStringName)] |
|||
public class AbpDeskMongoDbContext : AbpMongoDbContext |
|||
{ |
|||
public const string ConnectionStringName = "AbpDeskMongoBlog"; |
|||
|
|||
private static readonly Type[] EntityCollectionTypes = { |
|||
typeof(BlogPost) |
|||
}; |
|||
|
|||
public override IReadOnlyList<Type> GetEntityCollectionTypes() |
|||
{ |
|||
return EntityCollectionTypes; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using JetBrains.Annotations; |
|||
using Volo; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.ExtensionMethods; |
|||
|
|||
namespace AbpDesk.Blogging |
|||
{ |
|||
public class BlogPost : AggregateRoot |
|||
{ |
|||
public virtual string Title { get; protected set; } |
|||
|
|||
public virtual string Body { get; protected set; } |
|||
|
|||
public virtual ICollection<BlogPostComment> Comments { get; protected set; } |
|||
|
|||
protected BlogPost() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public BlogPost([NotNull] string title, [NotNull] string body) |
|||
{ |
|||
Id = Guid.NewGuid().ToString("D"); |
|||
|
|||
Check.NotNull(title, nameof(title)); |
|||
Check.NotNull(body, nameof(body)); |
|||
|
|||
Title = title; |
|||
Body = body; |
|||
|
|||
Comments = new List<BlogPostComment>(); |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return $"{base.ToString()}, Title = {Title}, Body = {Body.TruncateWithPostfix(32)}"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Domain.Entities; |
|||
|
|||
namespace AbpDesk.Blogging |
|||
{ |
|||
public class BlogPostComment : Entity |
|||
{ |
|||
[NotNull] |
|||
public virtual string Name { get; protected set; } |
|||
|
|||
[CanBeNull] |
|||
public virtual string Email { get; protected set; } |
|||
|
|||
public virtual byte? Star { get; protected set; } |
|||
|
|||
[NotNull] |
|||
public virtual string Message { get; protected set; } |
|||
|
|||
public BlogPostComment() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public BlogPostComment(string name, string message, string email = null, byte? star = null) |
|||
{ |
|||
Name = name; |
|||
Email = email; |
|||
Message = message; |
|||
Star = star; |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return $"{base.ToString()}, " + |
|||
$"Name = {Name}, " + |
|||
$"Email = {Email}, " + |
|||
$"Message = {Message}, " + |
|||
$"Star = {(Star.HasValue ? Star.Value.ToString() : "none")}"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System.Reflection; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
// General Information about an assembly is controlled through the following
|
|||
// set of attributes. Change these attribute values to modify the information
|
|||
// associated with an assembly.
|
|||
[assembly: AssemblyConfiguration("")] |
|||
[assembly: AssemblyCompany("")] |
|||
[assembly: AssemblyProduct("AbpDesk.MongoBlog")] |
|||
[assembly: AssemblyTrademark("")] |
|||
|
|||
// Setting ComVisible to false makes the types in this assembly not visible
|
|||
// to COM components. If you need to access a type in this assembly from
|
|||
// COM, set the ComVisible attribute to true on that type.
|
|||
[assembly: ComVisible(false)] |
|||
|
|||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|||
[assembly: Guid("63244dc7-34be-44e1-bf6f-f2672e59af36")] |
|||
@ -0,0 +1,15 @@ |
|||
{ |
|||
"version": "1.0.0-*", |
|||
|
|||
"dependencies": { |
|||
"NETStandard.Library": "1.6.1", |
|||
"Volo.Abp": "1.0.0-*", |
|||
"Volo.Abp.MongoDB": "1.0.0-*" |
|||
}, |
|||
|
|||
"frameworks": { |
|||
"netstandard1.6": { |
|||
"imports": "dnxcore50" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public class AbpDbContextRegistrationOptions : CommonDbContextRegistrationOptions, IAbpDbContextRegistrationOptionsBuilder |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -1,57 +0,0 @@ |
|||
using System; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Reflection; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public class AddAbpDbContextOptions |
|||
{ |
|||
internal RepositoryRegistrationOptions RepositoryOptions { get; set; } |
|||
|
|||
public AddAbpDbContextOptions() |
|||
{ |
|||
RepositoryOptions = new RepositoryRegistrationOptions(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Registers default repositories for this DbContext.
|
|||
/// </summary>
|
|||
/// <param name="includeAllEntities">
|
|||
/// Registers repositories only for aggregate root entities by default.
|
|||
/// set <see cref="includeAllEntities"/> to true to include all entities.
|
|||
/// </param>
|
|||
public void WithDefaultRepositories(bool includeAllEntities = false) |
|||
{ |
|||
RepositoryOptions.RegisterDefaultRepositories = true; |
|||
RepositoryOptions.IncludeAllEntitiesForDefaultRepositories = includeAllEntities; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Registers custom repository for a specific entity.
|
|||
/// Custom repositories overrides default repositories.
|
|||
/// </summary>
|
|||
/// <typeparam name="TEntity">Entity type</typeparam>
|
|||
/// <typeparam name="TRepository">Repository type</typeparam>
|
|||
public void WithCustomRepository<TEntity, TRepository>() |
|||
{ |
|||
WithCustomRepository(typeof(TEntity), typeof(TRepository)); |
|||
} |
|||
|
|||
private void WithCustomRepository(Type entityType, Type repositoryType) |
|||
{ |
|||
if (!ReflectionHelper.IsAssignableToGenericType(entityType, typeof(IEntity<>))) |
|||
{ |
|||
throw new AbpException($"Given entityType is not an entity: {entityType.AssemblyQualifiedName}. It must implement {typeof(IEntity<>).AssemblyQualifiedName}."); |
|||
} |
|||
|
|||
if (!ReflectionHelper.IsAssignableToGenericType(repositoryType, typeof(IRepository<,>))) |
|||
{ |
|||
throw new AbpException($"Given repositoryType is not a repository: {entityType.AssemblyQualifiedName}. It must implement {typeof(IRepository<,>).AssemblyQualifiedName}."); |
|||
} |
|||
|
|||
RepositoryOptions.CustomRepositories[entityType] = repositoryType; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public interface IAbpDbContextRegistrationOptionsBuilder : ICommonDbContextRegistrationOptionsBuilder |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -1,19 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
internal class RepositoryRegistrationOptions |
|||
{ |
|||
public bool RegisterDefaultRepositories { get; set; } |
|||
|
|||
public bool IncludeAllEntitiesForDefaultRepositories { get; set; } |
|||
|
|||
public Dictionary<Type, Type> CustomRepositories { get; set; } |
|||
|
|||
public RepositoryRegistrationOptions() |
|||
{ |
|||
CustomRepositories = new Dictionary<Type, Type>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,60 @@ |
|||
using System; |
|||
using System.Reflection; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Domain.Repositories.MongoDB; |
|||
using Volo.Abp.MongoDB; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public static class AbpMongoDbServiceCollectionExtensions |
|||
{ |
|||
public static IServiceCollection AddMongoDbContext<TMongoDbContext>(this IServiceCollection services, Action<IMongoDbContextRegistrationOptionsBuilder> optionsBuilder = null) //Created overload instead of default parameter
|
|||
where TMongoDbContext : AbpMongoDbContext |
|||
{ |
|||
var options = new MongoDbContextRegistrationOptions(); |
|||
optionsBuilder?.Invoke(options); |
|||
|
|||
AddRepositories<TMongoDbContext>(services, options); |
|||
|
|||
return services; |
|||
} |
|||
|
|||
private static void AddRepositories<TMongoDbContext>(IServiceCollection services, MongoDbContextRegistrationOptions options) |
|||
where TMongoDbContext : AbpMongoDbContext |
|||
{ |
|||
foreach (var customRepository in options.CustomRepositories) |
|||
{ |
|||
services.AddDefaultRepository(customRepository.Key, customRepository.Value); |
|||
} |
|||
|
|||
if (options.RegisterDefaultRepositories) |
|||
{ |
|||
RegisterDefaultRepositories(services, typeof(TMongoDbContext), options); |
|||
} |
|||
} |
|||
|
|||
private static void RegisterDefaultRepositories(IServiceCollection services, Type dbContextType, MongoDbContextRegistrationOptions options) |
|||
{ |
|||
var mongoDbContext = (AbpMongoDbContext) Activator.CreateInstance(dbContextType); |
|||
|
|||
foreach (var entityType in mongoDbContext.GetEntityCollectionTypes()) |
|||
{ |
|||
if (!options.ShouldRegisterDefaultRepositoryFor(entityType)) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
RegisterDefaultRepository(services, dbContextType, entityType, options); |
|||
} |
|||
} |
|||
|
|||
private static void RegisterDefaultRepository(IServiceCollection services, Type dbContextType, Type entityType, MongoDbContextRegistrationOptions options) |
|||
{ |
|||
var repositoryImplementationType = typeof(IEntity).GetTypeInfo().IsAssignableFrom(entityType) |
|||
? typeof(MongoDbRepository<,>).MakeGenericType(dbContextType, entityType) |
|||
: typeof(MongoDbRepository<,,>).MakeGenericType(dbContextType, entityType, EntityHelper.GetPrimaryKeyType(entityType)); |
|||
|
|||
services.AddDefaultRepository(entityType, repositoryImplementationType); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public interface IMongoDbContextRegistrationOptionsBuilder : ICommonDbContextRegistrationOptionsBuilder |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public class MongoDbContextRegistrationOptions : CommonDbContextRegistrationOptions, IMongoDbContextRegistrationOptionsBuilder |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.Abp.MongoDB |
|||
{ |
|||
public abstract class AbpMongoDbContext |
|||
{ |
|||
private static readonly Type[] EmptyTypeList = new Type[0]; |
|||
|
|||
public virtual IReadOnlyList<Type> GetEntityCollectionTypes() |
|||
{ |
|||
return EmptyTypeList; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Uow.MongoDB; |
|||
|
|||
namespace Volo.Abp.MongoDB |
|||
{ |
|||
public class AbpMongoDbModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
//TODO: ServiceCollection extensions to register mongodbcontext!
|
|||
|
|||
services.TryAddTransient(typeof(IMongoDatabaseProvider<>), typeof(UnitOfWorkMongoDatabaseProvider<>)); |
|||
services.AddAssemblyOf<AbpMongoDbModule>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using MongoDB.Driver; |
|||
|
|||
namespace Volo.Abp.MongoDB |
|||
{ |
|||
public interface IMongoDatabaseProvider<TMongoDbContext> |
|||
where TMongoDbContext : AbpMongoDbContext |
|||
{ |
|||
IMongoDatabase GetDatabase(); |
|||
} |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
using MongoDB.Driver; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.MongoDB; |
|||
|
|||
namespace Volo.Abp.Uow.MongoDB |
|||
{ |
|||
public class UnitOfWorkMongoDatabaseProvider<TMongoDbContext> : IMongoDatabaseProvider<TMongoDbContext> |
|||
where TMongoDbContext : AbpMongoDbContext |
|||
{ |
|||
private readonly IUnitOfWorkManager _unitOfWorkManager; |
|||
private readonly IConnectionStringResolver _connectionStringResolver; |
|||
|
|||
public UnitOfWorkMongoDatabaseProvider( |
|||
IUnitOfWorkManager unitOfWorkManager, |
|||
IConnectionStringResolver connectionStringResolver) |
|||
{ |
|||
_unitOfWorkManager = unitOfWorkManager; |
|||
_connectionStringResolver = connectionStringResolver; |
|||
} |
|||
|
|||
public IMongoDatabase GetDatabase() |
|||
{ |
|||
var unitOfWork = _unitOfWorkManager.Current; |
|||
if (unitOfWork == null) |
|||
{ |
|||
throw new AbpException("A IMongoDatabase instance can only be created inside a unit of work!"); |
|||
} |
|||
|
|||
var connectionString = _connectionStringResolver.Resolve<TMongoDbContext>(); |
|||
var dbContextKey = $"{typeof(TMongoDbContext).FullName}_{connectionString}"; |
|||
|
|||
string databaseName; |
|||
if (connectionString.Contains("|")) |
|||
{ |
|||
var splitted = connectionString.Split('|'); |
|||
connectionString = splitted[0]; |
|||
databaseName = splitted[1]; |
|||
} |
|||
else |
|||
{ |
|||
databaseName = ConnectionStringNameAttribute.GetConnStringName<TMongoDbContext>(); |
|||
} |
|||
|
|||
//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) |
|||
)); |
|||
|
|||
return ((MongoDbDatabaseApi)databaseApi).Database; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,69 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Reflection; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public class CommonDbContextRegistrationOptions : ICommonDbContextRegistrationOptionsBuilder |
|||
{ |
|||
public bool RegisterDefaultRepositories { get; set; } |
|||
|
|||
public bool IncludeAllEntitiesForDefaultRepositories { get; set; } |
|||
|
|||
public Dictionary<Type, Type> CustomRepositories { get; set; } |
|||
|
|||
public CommonDbContextRegistrationOptions() |
|||
{ |
|||
CustomRepositories = new Dictionary<Type, Type>(); |
|||
} |
|||
|
|||
public void WithDefaultRepositories(bool includeAllEntities = false) |
|||
{ |
|||
RegisterDefaultRepositories = true; |
|||
IncludeAllEntitiesForDefaultRepositories = includeAllEntities; |
|||
} |
|||
|
|||
public void WithCustomRepository<TEntity, TRepository>() |
|||
{ |
|||
WithCustomRepository(typeof(TEntity), typeof(TRepository)); |
|||
} |
|||
|
|||
private void WithCustomRepository(Type entityType, Type repositoryType) |
|||
{ |
|||
if (!ReflectionHelper.IsAssignableToGenericType(entityType, typeof(IEntity<>))) |
|||
{ |
|||
throw new AbpException($"Given entityType is not an entity: {entityType.AssemblyQualifiedName}. It must implement {typeof(IEntity<>).AssemblyQualifiedName}."); |
|||
} |
|||
|
|||
if (!ReflectionHelper.IsAssignableToGenericType(repositoryType, typeof(IRepository<,>))) |
|||
{ |
|||
throw new AbpException($"Given repositoryType is not a repository: {entityType.AssemblyQualifiedName}. It must implement {typeof(IRepository<,>).AssemblyQualifiedName}."); |
|||
} |
|||
|
|||
CustomRepositories[entityType] = repositoryType; |
|||
} |
|||
|
|||
public bool ShouldRegisterDefaultRepositoryFor(Type entityType) |
|||
{ |
|||
if (!RegisterDefaultRepositories) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (CustomRepositories.ContainsKey(entityType)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!IncludeAllEntitiesForDefaultRepositories && !ReflectionHelper.IsAssignableToGenericType(entityType, typeof(IAggregateRoot<>))) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public interface ICommonDbContextRegistrationOptionsBuilder |
|||
{ |
|||
/// <summary>
|
|||
/// Registers default repositories for this DbContext.
|
|||
/// </summary>
|
|||
/// <param name="includeAllEntities">
|
|||
/// Registers repositories only for aggregate root entities by default.
|
|||
/// set <see cref="includeAllEntities"/> to true to include all entities.
|
|||
/// </param>
|
|||
void WithDefaultRepositories(bool includeAllEntities = false); |
|||
|
|||
/// <summary>
|
|||
/// Registers custom repository for a specific entity.
|
|||
/// Custom repositories overrides default repositories.
|
|||
/// </summary>
|
|||
/// <typeparam name="TEntity">Entity type</typeparam>
|
|||
/// <typeparam name="TRepository">Repository type</typeparam>
|
|||
void WithCustomRepository<TEntity, TRepository>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
using System; |
|||
using System.Reflection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Reflection; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public static class ServiceCollectionRepositoryExtensions |
|||
{ |
|||
//TODO: validate repository and entity if they match!
|
|||
|
|||
public static void AddDefaultRepository(this IServiceCollection services, Type entityType, Type repositoryImplementationType) |
|||
{ |
|||
var primaryKeyType = EntityHelper.GetPrimaryKeyType(entityType); |
|||
|
|||
services.TryAddTransient( |
|||
typeof(IRepository<,>).MakeGenericType(entityType, primaryKeyType), |
|||
repositoryImplementationType |
|||
); |
|||
|
|||
services.TryAddTransient( //TODO: May not support IQueryableRepository
|
|||
typeof(IQueryableRepository<,>).MakeGenericType(entityType, primaryKeyType), |
|||
repositoryImplementationType |
|||
); |
|||
|
|||
if (BothSupportsDefaultPrimaryKey(entityType, repositoryImplementationType)) |
|||
{ |
|||
services.TryAddTransient( |
|||
typeof(IRepository<>).MakeGenericType(entityType), |
|||
repositoryImplementationType |
|||
); |
|||
|
|||
services.TryAddTransient( //TODO: May not support IQueryableRepository
|
|||
typeof(IQueryableRepository<>).MakeGenericType(entityType), |
|||
repositoryImplementationType |
|||
); |
|||
} |
|||
} |
|||
|
|||
private static bool BothSupportsDefaultPrimaryKey(Type entityType, Type repositoryImplementationType) |
|||
{ |
|||
return typeof(IEntity).GetTypeInfo().IsAssignableFrom(entityType) && |
|||
ReflectionHelper.IsAssignableToGenericType(repositoryImplementationType, typeof(IRepository<>)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using System.Threading; |
|||
using Volo.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Uow |
|||
{ |
|||
[ExposeServices(typeof(IAmbientUnitOfWork), typeof(IUnitOfWorkAccessor))] |
|||
public class AmbientUnitOfWork : IAmbientUnitOfWork, ISingletonDependency |
|||
{ |
|||
public IUnitOfWork UnitOfWork => _currentUowInfo.Value; |
|||
|
|||
private readonly AsyncLocal<IUnitOfWork> _currentUowInfo; |
|||
|
|||
public AmbientUnitOfWork() |
|||
{ |
|||
_currentUowInfo = new AsyncLocal<IUnitOfWork>(); |
|||
} |
|||
|
|||
public void SetUnitOfWork(IUnitOfWork unitOfWork) |
|||
{ |
|||
_currentUowInfo.Value = unitOfWork; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Uow |
|||
{ |
|||
public interface IAmbientUnitOfWork : IUnitOfWorkAccessor |
|||
{ |
|||
void SetUnitOfWork([CanBeNull] IUnitOfWork unitOfWork); |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Uow |
|||
{ |
|||
public interface IUnitOfWorkAccessor |
|||
{ |
|||
[CanBeNull] |
|||
IUnitOfWork UnitOfWork { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System.Threading; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Volo.Abp.Uow |
|||
{ |
|||
public static class UnitOfWorkExtensions |
|||
{ |
|||
//TODO: Implement all sync versions
|
|||
|
|||
public static void Complete([NotNull] this IUnitOfWork unitOfWork, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
Check.NotNull(unitOfWork, nameof(unitOfWork)); |
|||
|
|||
AsyncHelper.RunSync(() => unitOfWork.CompleteAsync(cancellationToken)); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue