Browse Source

Use IAbpLazyServiceProvider instead of property injection.

pull/6815/head
maliming 6 years ago
parent
commit
4b595a1427
  1. 60
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs
  2. 23
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs
  3. 14
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs
  4. 44
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
  5. 28
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs

60
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
namespace Volo.Abp.DependencyInjection
{
public class AbpLazyServiceProvider : IAbpLazyServiceProvider, ITransientDependency
{
protected IDictionary<Type, Lazy<object>> CachedTypes { get; set; }
protected IServiceProvider ServiceProvider { get; set; }
public AbpLazyServiceProvider(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
CachedTypes = new Dictionary<Type, Lazy<object>>();
}
public virtual T LazyGetRequiredService<T>()
{
return (T)CachedTypes.GetOrAdd(typeof(T), () => new Lazy<object>(() => (T) ServiceProvider.GetRequiredService(typeof(T)))).Value;
}
public virtual object LazyGetRequiredService(Type serviceType)
{
return CachedTypes.GetOrAdd(serviceType, () => new Lazy<object>(() => ServiceProvider.GetRequiredService(serviceType))).Value;
}
public virtual T LazyGetService<T>()
{
return (T)CachedTypes.GetOrAdd(typeof(T), () => new Lazy<object>(() => (T) ServiceProvider.GetService(typeof(T)))).Value;
}
public virtual object LazyGetService(Type serviceType)
{
return CachedTypes.GetOrAdd(serviceType, () => new Lazy<object>(() => ServiceProvider.GetService(serviceType))).Value;
}
public virtual T LazyGetService<T>(T defaultValue)
{
return LazyGetService<T>() ?? defaultValue;
}
public virtual object LazyGetService(Type serviceType, object defaultValue)
{
return LazyGetService(serviceType) ?? defaultValue;
}
public virtual object LazyGetService(Type serviceType, Func<IServiceProvider, object> factory)
{
return CachedTypes.GetOrAdd(serviceType, () => new Lazy<object>(() => factory(ServiceProvider))).Value;
}
public virtual T LazyGetService<T>(Func<IServiceProvider, object> factory)
{
return (T)CachedTypes.GetOrAdd(typeof(T), () => new Lazy<object>(() => factory(ServiceProvider))).Value;
}
}
}

23
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs

@ -0,0 +1,23 @@
using System;
namespace Volo.Abp.DependencyInjection
{
public interface IAbpLazyServiceProvider
{
T LazyGetRequiredService<T>();
object LazyGetRequiredService(Type serviceType);
T LazyGetService<T>();
object LazyGetService(Type serviceType);
T LazyGetService<T>(T defaultValue);
object LazyGetService(Type serviceType, object defaultValue);
object LazyGetService(Type serviceType, Func<IServiceProvider, object> factory);
T LazyGetService<T>(Func<IServiceProvider, object> factory);
}
}

14
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs

@ -19,21 +19,23 @@ namespace Volo.Abp.Domain.Repositories
IUnitOfWorkEnabled
where TEntity : class, IEntity
{
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
public IServiceProvider ServiceProvider { get; set; }
public IDataFilter DataFilter { get; set; }
public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService<IDataFilter>();
public ICurrentTenant CurrentTenant { get; set; }
public ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService<ICurrentTenant>();
public IAsyncQueryableExecuter AsyncExecuter { get; set; }
public IAsyncQueryableExecuter AsyncExecuter => LazyServiceProvider.LazyGetRequiredService<IAsyncQueryableExecuter>();
public IUnitOfWorkManager UnitOfWorkManager { get; set; }
public IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>();
public ICancellationTokenProvider CancellationTokenProvider { get; set; }
public ICancellationTokenProvider CancellationTokenProvider => LazyServiceProvider.LazyGetService<ICancellationTokenProvider>(NullCancellationTokenProvider.Instance);
protected BasicRepositoryBase()
{
CancellationTokenProvider = NullCancellationTokenProvider.Instance;
}
public abstract Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);

44
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs

@ -2,7 +2,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Nito.AsyncEx;
using System;
using System.Collections.Generic;
using System.Linq;
@ -32,14 +31,13 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
private readonly IDbContextProvider<TDbContext> _dbContextProvider;
private readonly Lazy<AbpEntityOptions<TEntity>> _entityOptionsLazy;
public virtual IGuidGenerator GuidGenerator { get; set; }
public virtual IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService<IGuidGenerator>(SimpleGuidGenerator.Instance);
public IEfCoreBulkOperationProvider BulkOperationProvider { get; set; }
public IEfCoreBulkOperationProvider BulkOperationProvider => LazyServiceProvider.LazyGetRequiredService<IEfCoreBulkOperationProvider>();
public EfCoreRepository(IDbContextProvider<TDbContext> dbContextProvider)
{
_dbContextProvider = dbContextProvider;
GuidGenerator = SimpleGuidGenerator.Instance;
_entityOptionsLazy = new Lazy<AbpEntityOptions<TEntity>>(
() => ServiceProvider
@ -49,15 +47,15 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
);
}
public async override Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
public override async Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
CheckAndSetId(entity);
var savedEntity = DbSet.Add(entity).Entity;
var savedEntity = (await DbSet.AddAsync(entity, GetCancellationToken(cancellationToken))).Entity;
if (autoSave)
{
await DbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
await DbContext.SaveChangesAsync(GetCancellationToken(GetCancellationToken(cancellationToken)));
}
return savedEntity;
@ -76,20 +74,20 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
this,
entities,
autoSave,
cancellationToken
GetCancellationToken(cancellationToken)
);
return;
}
await DbSet.AddRangeAsync(entities);
await DbSet.AddRangeAsync(entities, GetCancellationToken(cancellationToken));
if (autoSave)
{
await DbContext.SaveChangesAsync();
await DbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
}
}
public async override Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
public override async Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
DbContext.Attach(entity);
@ -111,7 +109,7 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
this,
entities,
autoSave,
cancellationToken
GetCancellationToken(cancellationToken)
);
return;
@ -121,11 +119,11 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
if (autoSave)
{
await DbContext.SaveChangesAsync();
await DbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
}
}
public async override Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
public override async Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
DbSet.Remove(entity);
@ -152,23 +150,23 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
if (autoSave)
{
await DbContext.SaveChangesAsync();
await DbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
}
}
public async override Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
public override async Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
return includeDetails
? await WithDetails().ToListAsync(GetCancellationToken(cancellationToken))
: await DbSet.ToListAsync(GetCancellationToken(cancellationToken));
}
public async override Task<long> GetCountAsync(CancellationToken cancellationToken = default)
public override async Task<long> GetCountAsync(CancellationToken cancellationToken = default)
{
return await DbSet.LongCountAsync(GetCancellationToken(cancellationToken));
}
public async override Task<List<TEntity>> GetPagedListAsync(
public override async Task<List<TEntity>> GetPagedListAsync(
int skipCount,
int maxResultCount,
string sorting,
@ -190,10 +188,10 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
protected override Task SaveChangesAsync(CancellationToken cancellationToken)
{
return DbContext.SaveChangesAsync(cancellationToken);
return DbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
}
public async override Task<TEntity> FindAsync(
public override async Task<TEntity> FindAsync(
Expression<Func<TEntity, bool>> predicate,
bool includeDetails = true,
CancellationToken cancellationToken = default)
@ -207,7 +205,7 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
.SingleOrDefaultAsync(GetCancellationToken(cancellationToken));
}
public async override Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
public override async Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
{
var entities = await GetQueryable()
.Where(predicate)
@ -344,9 +342,9 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
await DeleteAsync(entity, autoSave, cancellationToken);
}
public async virtual Task DeleteManyAsync([NotNull] IEnumerable<TKey> ids, bool autoSave = false, CancellationToken cancellationToken = default)
public virtual async Task DeleteManyAsync([NotNull] IEnumerable<TKey> ids, bool autoSave = false, CancellationToken cancellationToken = default)
{
var entities = await DbSet.Where(x => ids.Contains(x.Id)).ToListAsync();
var entities = await DbSet.Where(x => ids.Contains(x.Id)).ToListAsync(GetCancellationToken(cancellationToken));
await DeleteManyAsync(entities, autoSave, cancellationToken);
}

28
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs

@ -23,7 +23,6 @@ using Volo.Abp.EntityFrameworkCore.EntityHistory;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.EntityFrameworkCore.ValueConverters;
using Volo.Abp.Guids;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Reflection;
@ -35,31 +34,33 @@ namespace Volo.Abp.EntityFrameworkCore
public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext, ITransientDependency
where TDbContext : DbContext
{
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
protected virtual Guid? CurrentTenantId => CurrentTenant?.Id;
protected virtual bool IsMultiTenantFilterEnabled => DataFilter?.IsEnabled<IMultiTenant>() ?? false;
protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled<ISoftDelete>() ?? false;
public ICurrentTenant CurrentTenant { get; set; }
public ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService<ICurrentTenant>();
public IGuidGenerator GuidGenerator { get; set; }
public IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetService<IGuidGenerator>(SimpleGuidGenerator.Instance);
public IDataFilter DataFilter { get; set; }
public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService<IDataFilter>();
public IEntityChangeEventHelper EntityChangeEventHelper { get; set; }
public IEntityChangeEventHelper EntityChangeEventHelper => LazyServiceProvider.LazyGetService<IEntityChangeEventHelper>(NullEntityChangeEventHelper.Instance);
public IAuditPropertySetter AuditPropertySetter { get; set; }
public IAuditPropertySetter AuditPropertySetter => LazyServiceProvider.LazyGetRequiredService<IAuditPropertySetter>();
public IEntityHistoryHelper EntityHistoryHelper { get; set; }
public IEntityHistoryHelper EntityHistoryHelper => LazyServiceProvider.LazyGetService<IEntityHistoryHelper>(NullEntityHistoryHelper.Instance);
public IAuditingManager AuditingManager { get; set; }
public IAuditingManager AuditingManager => LazyServiceProvider.LazyGetRequiredService<IAuditingManager>();
public IUnitOfWorkManager UnitOfWorkManager { get; set; }
public IUnitOfWorkManager UnitOfWorkManager => LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>();
public IClock Clock { get; set; }
public IClock Clock => LazyServiceProvider.LazyGetRequiredService<IClock>();
public ILogger<AbpDbContext<TDbContext>> Logger { get; set; }
public ILogger<AbpDbContext<TDbContext>> Logger => LazyServiceProvider.LazyGetService<ILogger<AbpDbContext<TDbContext>>>(NullLogger<AbpDbContext<TDbContext>>.Instance);
private static readonly MethodInfo ConfigureBasePropertiesMethodInfo
= typeof(AbpDbContext<TDbContext>)
@ -85,10 +86,7 @@ namespace Volo.Abp.EntityFrameworkCore
protected AbpDbContext(DbContextOptions<TDbContext> options)
: base(options)
{
GuidGenerator = SimpleGuidGenerator.Instance;
EntityChangeEventHelper = NullEntityChangeEventHelper.Instance;
EntityHistoryHelper = NullEntityHistoryHelper.Instance;
Logger = NullLogger<AbpDbContext<TDbContext>>.Instance;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)

Loading…
Cancel
Save