Creates basic UOW classes and revised codebase.

pull/81/head
Halil İbrahim Kalkan 9 years ago
parent 08dd58c92e
commit d3c613d121

@ -1,14 +1,8 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.Data;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Repositories.EntityFrameworkCore;
using Volo.ExtensionMethods.Collections.Generic;
namespace Microsoft.Extensions.DependencyInjection
{
@ -23,32 +17,7 @@ namespace Microsoft.Extensions.DependencyInjection
.AddLogging();
services.TryAddTransient<TDbContext>();
services.TryAddSingleton(serviceProvider =>
{
const string moduleName = ""; //TODO: Use AbpModuleDescriptor instead of module name?
var connInfoResolver = serviceProvider.GetRequiredService<IConnectionStringResolver>();
var context = new AbpDbContextConfigurationContext<TDbContext>(connInfoResolver.Resolve(moduleName), moduleName);
var dbContextOptions = serviceProvider.GetRequiredService<IOptions<AbpDbContextOptions>>().Value;
var configureAction = dbContextOptions.ConfigureActions.GetOrDefault(typeof(TDbContext));
if (configureAction != null)
{
((Action<AbpDbContextConfigurationContext<TDbContext>>) configureAction).Invoke(context);
}
else if(dbContextOptions.DefaultConfigureAction != null)
{
dbContextOptions.DefaultConfigureAction.Invoke(context);
}
else
{
throw new AbpException("Should set a configure action for dbcontext"); //TODO: Better message
}
return context.DbContextOptions.Options;
});
services.TryAddSingleton(DbContextOptionsFactory.Create<TDbContext>);
return services;
}

@ -0,0 +1,44 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.ExtensionMethods.Collections.Generic;
namespace Microsoft.Extensions.DependencyInjection
{
internal static class DbContextOptionsFactory
{
public static DbContextOptions<TDbContext> Create<TDbContext>(IServiceProvider serviceProvider)
where TDbContext : AbpDbContext<TDbContext>
{
const string moduleName = ""; //TODO: Use AbpModuleDescriptor instead of module name?
using (var scope = serviceProvider.CreateScope())
{
var connInfoResolver = scope.ServiceProvider.GetRequiredService<IConnectionStringResolver>();
var context = new AbpDbContextConfigurationContext<TDbContext>(connInfoResolver.Resolve(moduleName), moduleName);
var dbContextOptions = scope.ServiceProvider.GetRequiredService<IOptions<AbpDbContextOptions>>().Value;
var configureAction = dbContextOptions.ConfigureActions.GetOrDefault(typeof(TDbContext));
if (configureAction != null)
{
((Action<AbpDbContextConfigurationContext<TDbContext>>)configureAction).Invoke(context);
}
else if (dbContextOptions.DefaultConfigureAction != null)
{
dbContextOptions.DefaultConfigureAction.Invoke(context);
}
else
{
throw new AbpException("Should set a configure action for dbcontext"); //TODO: Better message
}
return context.DbContextOptions.Options;
}
}
}
}

@ -10,7 +10,7 @@ namespace Volo.Abp.EntityFrameworkCore
public override void ConfigureServices(IServiceCollection services)
{
//TODO: This will be changed!
services.TryAddTransient(typeof(IDbContextProvider<>), typeof(DefaultDbContextProvider<>));
services.TryAddTransient(typeof(IDbContextProvider<>), typeof(UnitOfWorkDbContextProvider<>));
}
}
}

@ -1,20 +0,0 @@
using Volo.Abp.EntityFrameworkCore;
namespace Volo.Abp.Repositories.EntityFrameworkCore
{
public class DefaultDbContextProvider<TDbContext> : IDbContextProvider<TDbContext>
where TDbContext : AbpDbContext<TDbContext>
{
private readonly TDbContext _dbContext;
public DefaultDbContextProvider(TDbContext dbContext) //TODO: Should create this dynamically!
{
_dbContext = dbContext;
}
public TDbContext GetDbContext()
{
return _dbContext;
}
}
}

@ -0,0 +1,31 @@
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Uow;
namespace Volo.Abp.Repositories.EntityFrameworkCore
{
public class UnitOfWorkDbContextProvider<TDbContext> : IDbContextProvider<TDbContext>
where TDbContext : AbpDbContext<TDbContext>
{
private readonly TDbContext _dbContext;
private readonly IUnitOfWorkManager _unitOfWorkManager;
public UnitOfWorkDbContextProvider(
TDbContext dbContext,
IUnitOfWorkManager unitOfWorkManager) //TODO: Should create this dynamically inside a unit of work.
{
_dbContext = dbContext;
_unitOfWorkManager = unitOfWorkManager;
}
public TDbContext GetDbContext()
{
//if (_unitOfWorkManager.Current == null)
//{
// throw new AbpException("A DbContext can only be created inside a unit of work!");
//}
return _dbContext;
}
}
}

@ -8,15 +8,15 @@ namespace Volo.Abp.MultiTenancy
{
public TenantScope CurrentScope
{
get { return _tenant.Value; }
private set { _tenant.Value = value; }
get { return _currentScope.Value; }
private set { _currentScope.Value = value; }
}
private readonly AsyncLocal<TenantScope> _tenant;
private readonly AsyncLocal<TenantScope> _currentScope;
public AsyncLocalTenantScopeProvider()
{
_tenant = new AsyncLocal<TenantScope>();
_currentScope = new AsyncLocal<TenantScope>();
}
public IDisposable EnterScope(TenantInfo tenantInfo)

@ -0,0 +1,32 @@
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Volo.Abp.Uow
{
internal class ChildUnitOfWork : IUnitOfWork
{
private readonly IUnitOfWork _parent;
public ChildUnitOfWork([NotNull] IUnitOfWork parent)
{
Check.NotNull(parent, nameof(parent));
_parent = parent;
}
public Task SaveChangesAsync()
{
return _parent.SaveChangesAsync();
}
public Task CompleteAsync()
{
return Task.CompletedTask;
}
public void Dispose()
{
}
}
}

@ -0,0 +1,13 @@
using System;
using System.Threading.Tasks;
using Volo.DependencyInjection;
namespace Volo.Abp.Uow
{
public interface IUnitOfWork : IDisposable, ITransientDependency
{
Task SaveChangesAsync();
Task CompleteAsync();
}
}

@ -0,0 +1,9 @@
namespace Volo.Abp.Uow
{
public interface IUnitOfWorkManager
{
IUnitOfWork Current { get; }
IUnitOfWork Begin();
}
}

@ -0,0 +1,23 @@
using System;
using System.Threading.Tasks;
namespace Volo.Abp.Uow
{
public class UnitOfWork : IUnitOfWork
{
public void Dispose()
{
throw new NotImplementedException();
}
public Task SaveChangesAsync()
{
throw new NotImplementedException();
}
public Task CompleteAsync()
{
throw new NotImplementedException();
}
}
}

@ -0,0 +1,17 @@
using Microsoft.Extensions.DependencyInjection;
namespace Volo.Abp.Uow
{
internal class UnitOfWorkInfo
{
public IUnitOfWork UnitOfWork { get; set; }
public IServiceScope ServiceScope { get; set; }
public UnitOfWorkInfo(IUnitOfWork unitOfWork, IServiceScope serviceScope)
{
UnitOfWork = unitOfWork;
ServiceScope = serviceScope;
}
}
}

@ -0,0 +1,48 @@
using System;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
using Volo.DependencyInjection;
namespace Volo.Abp.Uow
{
public class UnitOfWorkManager : IUnitOfWorkManager, ISingletonDependency
{
//TODO: Skipped many feature of Abp 1.x
public IUnitOfWork Current => _currentUowInfo.Value?.UnitOfWork;
private readonly AsyncLocal<UnitOfWorkInfo> _currentUowInfo;
private readonly IServiceProvider _serviceProvider;
public UnitOfWorkManager(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_currentUowInfo = new AsyncLocal<UnitOfWorkInfo>();
}
public IUnitOfWork Begin()
{
if (Current != null)
{
return new ChildUnitOfWork(Current);
}
var scope = _serviceProvider.CreateScope();
try
{
_currentUowInfo.Value = new UnitOfWorkInfo(
scope.ServiceProvider.GetRequiredService<IUnitOfWork>(),
scope
);
}
catch
{
scope.Dispose();
throw;
}
return Current;
}
}
}

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.DependencyInjection;
namespace Microsoft.Extensions.DependencyInjection
{
public class AbpDependencyInjectionSpecifications
{
//TODO: Tests...
public class MyScopedClass : IScopedDependency
{
}
}
}
Loading…
Cancel
Save