Browse Source

Merge pull request #3184 from abpframework/Cotur-Virtualization-TenantManagement

Make TenantManagement module services easily overridable by inheritance
pull/3205/head
Halil İbrahim Kalkan 6 years ago
committed by GitHub
parent
commit
a1fca1d76a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs
  2. 10
      modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs
  3. 44
      modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs
  4. 6
      modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/EfCoreTenantRepository.cs
  5. 28
      modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs
  6. 6
      modules/tenant-management/src/Volo.Abp.TenantManagement.MongoDB/Volo/Abp/TenantManagement/MongoDb/MongoTenantRepository.cs
  7. 2
      modules/tenant-management/src/Volo.Abp.TenantManagement.Web/AbpTenantManagementWebAutoMapperProfile.cs
  8. 2
      modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs
  9. 14
      modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/ConnectionStringsModal.cshtml.cs
  10. 13
      modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/CreateModal.cshtml.cs
  11. 12
      modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/EditModal.cshtml.cs
  12. 8
      modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.cshtml.cs

2
modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs

@ -72,7 +72,7 @@ namespace Volo.Abp.TenantManagement
}
}
internal void SetName([NotNull] string name)
protected internal virtual void SetName([NotNull] string name)
{
Name = Check.NotNullOrWhiteSpace(name, nameof(name), TenantConsts.MaxNameLength);
}

10
modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs

@ -7,15 +7,15 @@ namespace Volo.Abp.TenantManagement
{
public class TenantManager : DomainService, ITenantManager
{
private readonly ITenantRepository _tenantRepository;
protected ITenantRepository TenantRepository { get; }
public TenantManager(ITenantRepository tenantRepository)
{
_tenantRepository = tenantRepository;
TenantRepository = tenantRepository;
}
public async Task<Tenant> CreateAsync(string name)
public virtual async Task<Tenant> CreateAsync(string name)
{
Check.NotNull(name, nameof(name));
@ -23,7 +23,7 @@ namespace Volo.Abp.TenantManagement
return new Tenant(GuidGenerator.Create(), name);
}
public async Task ChangeNameAsync(Tenant tenant, string name)
public virtual async Task ChangeNameAsync(Tenant tenant, string name)
{
Check.NotNull(tenant, nameof(tenant));
Check.NotNull(name, nameof(name));
@ -34,7 +34,7 @@ namespace Volo.Abp.TenantManagement
protected virtual async Task ValidateNameAsync(string name, Guid? expectedId = null)
{
var tenant = await _tenantRepository.FindByNameAsync(name);
var tenant = await TenantRepository.FindByNameAsync(name);
if (tenant != null && tenant.Id != expectedId)
{
throw new UserFriendlyException("Duplicate tenancy name: " + name); //TODO: A domain exception would be better..?

44
modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs

@ -10,73 +10,73 @@ namespace Volo.Abp.TenantManagement
public class TenantStore : ITenantStore, ITransientDependency
{
private readonly ITenantRepository _tenantRepository;
private readonly IObjectMapper<AbpTenantManagementDomainModule> _objectMapper;
private readonly ICurrentTenant _currentTenant;
protected ITenantRepository TenantRepository { get; }
protected IObjectMapper<AbpTenantManagementDomainModule> ObjectMapper { get; }
protected ICurrentTenant CurrentTenant { get; }
public TenantStore(
ITenantRepository tenantRepository,
IObjectMapper<AbpTenantManagementDomainModule> objectMapper,
ICurrentTenant currentTenant)
{
_tenantRepository = tenantRepository;
_objectMapper = objectMapper;
_currentTenant = currentTenant;
TenantRepository = tenantRepository;
ObjectMapper = objectMapper;
CurrentTenant = currentTenant;
}
public async Task<TenantConfiguration> FindAsync(string name)
public virtual async Task<TenantConfiguration> FindAsync(string name)
{
using (_currentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities!
using (CurrentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities!
{
var tenant = await _tenantRepository.FindByNameAsync(name);
var tenant = await TenantRepository.FindByNameAsync(name);
if (tenant == null)
{
return null;
}
return _objectMapper.Map<Tenant, TenantConfiguration>(tenant);
return ObjectMapper.Map<Tenant, TenantConfiguration>(tenant);
}
}
public async Task<TenantConfiguration> FindAsync(Guid id)
public virtual async Task<TenantConfiguration> FindAsync(Guid id)
{
using (_currentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities!
using (CurrentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities!
{
var tenant = await _tenantRepository.FindAsync(id);
var tenant = await TenantRepository.FindAsync(id);
if (tenant == null)
{
return null;
}
return _objectMapper.Map<Tenant, TenantConfiguration>(tenant);
return ObjectMapper.Map<Tenant, TenantConfiguration>(tenant);
}
}
public TenantConfiguration Find(string name)
public virtual TenantConfiguration Find(string name)
{
using (_currentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities!
using (CurrentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities!
{
var tenant = _tenantRepository.FindByName(name);
var tenant = TenantRepository.FindByName(name);
if (tenant == null)
{
return null;
}
return _objectMapper.Map<Tenant, TenantConfiguration>(tenant);
return ObjectMapper.Map<Tenant, TenantConfiguration>(tenant);
}
}
public TenantConfiguration Find(Guid id)
public virtual TenantConfiguration Find(Guid id)
{
using (_currentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities!
using (CurrentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities!
{
var tenant = _tenantRepository.FindById(id);
var tenant = TenantRepository.FindById(id);
if (tenant == null)
{
return null;
}
return _objectMapper.Map<Tenant, TenantConfiguration>(tenant);
return ObjectMapper.Map<Tenant, TenantConfiguration>(tenant);
}
}
}

6
modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/EfCoreTenantRepository.cs

@ -28,14 +28,14 @@ namespace Volo.Abp.TenantManagement.EntityFrameworkCore
.FirstOrDefaultAsync(t => t.Name == name, GetCancellationToken(cancellationToken));
}
public Tenant FindByName(string name, bool includeDetails = true)
public virtual Tenant FindByName(string name, bool includeDetails = true)
{
return DbSet
.IncludeDetails(includeDetails)
.FirstOrDefault(t => t.Name == name);
}
public Tenant FindById(Guid id, bool includeDetails = true)
public virtual Tenant FindById(Guid id, bool includeDetails = true)
{
return DbSet
.IncludeDetails(includeDetails)
@ -62,7 +62,7 @@ namespace Volo.Abp.TenantManagement.EntityFrameworkCore
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<long> GetCountAsync(string filter = null, CancellationToken cancellationToken = default)
public virtual async Task<long> GetCountAsync(string filter = null, CancellationToken cancellationToken = default)
{
return await this
.WhereIf(

28
modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs

@ -12,66 +12,66 @@ namespace Volo.Abp.TenantManagement
[Route("api/multi-tenancy/tenants")]
public class TenantController : AbpController, ITenantAppService //TODO: Throws exception on validation if we inherit from Controller
{
private readonly ITenantAppService _service;
protected ITenantAppService TenantAppService { get; }
public TenantController(ITenantAppService service)
public TenantController(ITenantAppService tenantAppService)
{
_service = service;
TenantAppService = tenantAppService;
}
[HttpGet]
[Route("{id}")]
public virtual Task<TenantDto> GetAsync(Guid id)
{
return _service.GetAsync(id);
return TenantAppService.GetAsync(id);
}
[HttpGet]
public virtual Task<PagedResultDto<TenantDto>> GetListAsync(GetTenantsInput input)
{
return _service.GetListAsync(input);
return TenantAppService.GetListAsync(input);
}
[HttpPost]
public virtual Task<TenantDto> CreateAsync(TenantCreateDto input)
{
ValidateModel();
return _service.CreateAsync(input);
return TenantAppService.CreateAsync(input);
}
[HttpPut]
[Route("{id}")]
public virtual Task<TenantDto> UpdateAsync(Guid id, TenantUpdateDto input)
{
return _service.UpdateAsync(id, input);
return TenantAppService.UpdateAsync(id, input);
}
[HttpDelete]
[Route("{id}")]
public virtual Task DeleteAsync(Guid id)
{
return _service.DeleteAsync(id);
return TenantAppService.DeleteAsync(id);
}
[HttpGet]
[Route("{id}/default-connection-string")]
public Task<string> GetDefaultConnectionStringAsync(Guid id)
public virtual Task<string> GetDefaultConnectionStringAsync(Guid id)
{
return _service.GetDefaultConnectionStringAsync(id);
return TenantAppService.GetDefaultConnectionStringAsync(id);
}
[HttpPut]
[Route("{id}/default-connection-string")]
public Task UpdateDefaultConnectionStringAsync(Guid id, string defaultConnectionString)
public virtual Task UpdateDefaultConnectionStringAsync(Guid id, string defaultConnectionString)
{
return _service.UpdateDefaultConnectionStringAsync(id, defaultConnectionString);
return TenantAppService.UpdateDefaultConnectionStringAsync(id, defaultConnectionString);
}
[HttpDelete]
[Route("{id}/default-connection-string")]
public Task DeleteDefaultConnectionStringAsync(Guid id)
public virtual Task DeleteDefaultConnectionStringAsync(Guid id)
{
return _service.DeleteDefaultConnectionStringAsync(id);
return TenantAppService.DeleteDefaultConnectionStringAsync(id);
}
}
}

6
modules/tenant-management/src/Volo.Abp.TenantManagement.MongoDB/Volo/Abp/TenantManagement/MongoDb/MongoTenantRepository.cs

@ -28,13 +28,13 @@ namespace Volo.Abp.TenantManagement.MongoDB
.FirstOrDefaultAsync(t => t.Name == name, GetCancellationToken(cancellationToken));
}
public Tenant FindByName(string name, bool includeDetails = true)
public virtual Tenant FindByName(string name, bool includeDetails = true)
{
return GetMongoQueryable()
.FirstOrDefault(t => t.Name == name);
}
public Tenant FindById(Guid id, bool includeDetails = true)
public virtual Tenant FindById(Guid id, bool includeDetails = true)
{
return GetMongoQueryable()
.FirstOrDefault(t => t.Id == id);
@ -60,7 +60,7 @@ namespace Volo.Abp.TenantManagement.MongoDB
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<long> GetCountAsync(string filter = null, CancellationToken cancellationToken = default)
public virtual async Task<long> GetCountAsync(string filter = null, CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
.WhereIf<Tenant, IMongoQueryable<Tenant>>(

2
modules/tenant-management/src/Volo.Abp.TenantManagement.Web/AbpTenantManagementWebAutoMapperProfile.cs

@ -10,7 +10,7 @@ namespace Volo.Abp.TenantManagement.Web
CreateRoleMappings();
}
private void CreateRoleMappings()
protected virtual void CreateRoleMappings()
{
//List
CreateMap<TenantDto, EditModalModel.TenantInfoModel>();

2
modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Navigation/AbpTenantManagementWebMainMenuContributor.cs

@ -9,7 +9,7 @@ namespace Volo.Abp.TenantManagement.Web.Navigation
{
public class AbpTenantManagementWebMainMenuContributor : IMenuContributor
{
public async Task ConfigureMenuAsync(MenuConfigurationContext context)
public virtual async Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if (context.Menu.Name != StandardMenus.Main)
{

14
modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/ConnectionStringsModal.cshtml.cs

@ -11,16 +11,16 @@ namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants
[BindProperty]
public TenantInfoModel Tenant { get; set; }
private readonly ITenantAppService _tenantAppService;
protected ITenantAppService TenantAppService { get; }
public ConnectionStringsModal(ITenantAppService tenantAppService)
{
_tenantAppService = tenantAppService;
TenantAppService = tenantAppService;
}
public async Task OnGetAsync(Guid id)
public virtual async Task OnGetAsync(Guid id)
{
var defaultConnectionString = await _tenantAppService.GetDefaultConnectionStringAsync(id);
var defaultConnectionString = await TenantAppService.GetDefaultConnectionStringAsync(id);
Tenant = new TenantInfoModel
{
Id = id,
@ -29,17 +29,17 @@ namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants
};
}
public async Task<IActionResult> OnPostAsync()
public virtual async Task<IActionResult> OnPostAsync()
{
ValidateModel();
if (Tenant.UseSharedDatabase || Tenant.DefaultConnectionString.IsNullOrWhiteSpace())
{
await _tenantAppService.DeleteDefaultConnectionStringAsync(Tenant.Id);
await TenantAppService.DeleteDefaultConnectionStringAsync(Tenant.Id);
}
else
{
await _tenantAppService.UpdateDefaultConnectionStringAsync(Tenant.Id, Tenant.DefaultConnectionString);
await TenantAppService.UpdateDefaultConnectionStringAsync(Tenant.Id, Tenant.DefaultConnectionString);
}
return NoContent();

13
modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/CreateModal.cshtml.cs

@ -10,19 +10,24 @@ namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants
[BindProperty]
public TenantInfoModel Tenant { get; set; }
private readonly ITenantAppService _tenantAppService;
protected ITenantAppService TenantAppService { get; }
public CreateModalModel(ITenantAppService tenantAppService)
{
_tenantAppService = tenantAppService;
TenantAppService = tenantAppService;
}
public async Task<IActionResult> OnPostAsync()
public virtual Task OnGetAsync()
{
return Task.CompletedTask;
}
public virtual async Task<IActionResult> OnPostAsync()
{
ValidateModel();
var input = ObjectMapper.Map<TenantInfoModel, TenantCreateDto>(Tenant);
await _tenantAppService.CreateAsync(input);
await TenantAppService.CreateAsync(input);
return NoContent();
}

12
modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/EditModal.cshtml.cs

@ -11,26 +11,26 @@ namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants
[BindProperty]
public TenantInfoModel Tenant { get; set; }
private readonly ITenantAppService _tenantAppService;
protected ITenantAppService TenantAppService { get; }
public EditModalModel(ITenantAppService tenantAppService)
{
_tenantAppService = tenantAppService;
TenantAppService = tenantAppService;
}
public async Task OnGetAsync(Guid id)
public virtual async Task OnGetAsync(Guid id)
{
Tenant = ObjectMapper.Map<TenantDto, TenantInfoModel>(
await _tenantAppService.GetAsync(id)
await TenantAppService.GetAsync(id)
);
}
public async Task<IActionResult> OnPostAsync()
public virtual async Task<IActionResult> OnPostAsync()
{
ValidateModel();
var input = ObjectMapper.Map<TenantInfoModel, TenantUpdateDto>(Tenant);
await _tenantAppService.UpdateAsync(Tenant.Id, input);
await TenantAppService.UpdateAsync(Tenant.Id, input);
return NoContent();
}

8
modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.cshtml.cs

@ -1,12 +1,18 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants
{
public class IndexModel : TenantManagementPageModel
{
public void OnGet()
public virtual Task OnGetAsync()
{
return Task.CompletedTask;
}
public virtual Task OnPostAsync()
{
return Task.CompletedTask;
}
}
}
Loading…
Cancel
Save