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 7 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); 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 public class TenantManager : DomainService, ITenantManager
{ {
private readonly ITenantRepository _tenantRepository; protected ITenantRepository TenantRepository { get; }
public TenantManager(ITenantRepository tenantRepository) 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)); Check.NotNull(name, nameof(name));
@ -23,7 +23,7 @@ namespace Volo.Abp.TenantManagement
return new Tenant(GuidGenerator.Create(), name); 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(tenant, nameof(tenant));
Check.NotNull(name, nameof(name)); Check.NotNull(name, nameof(name));
@ -34,7 +34,7 @@ namespace Volo.Abp.TenantManagement
protected virtual async Task ValidateNameAsync(string name, Guid? expectedId = null) 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) if (tenant != null && tenant.Id != expectedId)
{ {
throw new UserFriendlyException("Duplicate tenancy name: " + name); //TODO: A domain exception would be better..? 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 public class TenantStore : ITenantStore, ITransientDependency
{ {
private readonly ITenantRepository _tenantRepository; protected ITenantRepository TenantRepository { get; }
private readonly IObjectMapper<AbpTenantManagementDomainModule> _objectMapper; protected IObjectMapper<AbpTenantManagementDomainModule> ObjectMapper { get; }
private readonly ICurrentTenant _currentTenant; protected ICurrentTenant CurrentTenant { get; }
public TenantStore( public TenantStore(
ITenantRepository tenantRepository, ITenantRepository tenantRepository,
IObjectMapper<AbpTenantManagementDomainModule> objectMapper, IObjectMapper<AbpTenantManagementDomainModule> objectMapper,
ICurrentTenant currentTenant) ICurrentTenant currentTenant)
{ {
_tenantRepository = tenantRepository; TenantRepository = tenantRepository;
_objectMapper = objectMapper; ObjectMapper = objectMapper;
_currentTenant = currentTenant; 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) if (tenant == null)
{ {
return 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) if (tenant == null)
{ {
return 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) if (tenant == null)
{ {
return 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) if (tenant == null)
{ {
return 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)); .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 return DbSet
.IncludeDetails(includeDetails) .IncludeDetails(includeDetails)
.FirstOrDefault(t => t.Name == name); .FirstOrDefault(t => t.Name == name);
} }
public Tenant FindById(Guid id, bool includeDetails = true) public virtual Tenant FindById(Guid id, bool includeDetails = true)
{ {
return DbSet return DbSet
.IncludeDetails(includeDetails) .IncludeDetails(includeDetails)
@ -62,7 +62,7 @@ namespace Volo.Abp.TenantManagement.EntityFrameworkCore
.ToListAsync(GetCancellationToken(cancellationToken)); .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 return await this
.WhereIf( .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")] [Route("api/multi-tenancy/tenants")]
public class TenantController : AbpController, ITenantAppService //TODO: Throws exception on validation if we inherit from Controller 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] [HttpGet]
[Route("{id}")] [Route("{id}")]
public virtual Task<TenantDto> GetAsync(Guid id) public virtual Task<TenantDto> GetAsync(Guid id)
{ {
return _service.GetAsync(id); return TenantAppService.GetAsync(id);
} }
[HttpGet] [HttpGet]
public virtual Task<PagedResultDto<TenantDto>> GetListAsync(GetTenantsInput input) public virtual Task<PagedResultDto<TenantDto>> GetListAsync(GetTenantsInput input)
{ {
return _service.GetListAsync(input); return TenantAppService.GetListAsync(input);
} }
[HttpPost] [HttpPost]
public virtual Task<TenantDto> CreateAsync(TenantCreateDto input) public virtual Task<TenantDto> CreateAsync(TenantCreateDto input)
{ {
ValidateModel(); ValidateModel();
return _service.CreateAsync(input); return TenantAppService.CreateAsync(input);
} }
[HttpPut] [HttpPut]
[Route("{id}")] [Route("{id}")]
public virtual Task<TenantDto> UpdateAsync(Guid id, TenantUpdateDto input) public virtual Task<TenantDto> UpdateAsync(Guid id, TenantUpdateDto input)
{ {
return _service.UpdateAsync(id, input); return TenantAppService.UpdateAsync(id, input);
} }
[HttpDelete] [HttpDelete]
[Route("{id}")] [Route("{id}")]
public virtual Task DeleteAsync(Guid id) public virtual Task DeleteAsync(Guid id)
{ {
return _service.DeleteAsync(id); return TenantAppService.DeleteAsync(id);
} }
[HttpGet] [HttpGet]
[Route("{id}/default-connection-string")] [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] [HttpPut]
[Route("{id}/default-connection-string")] [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] [HttpDelete]
[Route("{id}/default-connection-string")] [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)); .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() return GetMongoQueryable()
.FirstOrDefault(t => t.Name == name); .FirstOrDefault(t => t.Name == name);
} }
public Tenant FindById(Guid id, bool includeDetails = true) public virtual Tenant FindById(Guid id, bool includeDetails = true)
{ {
return GetMongoQueryable() return GetMongoQueryable()
.FirstOrDefault(t => t.Id == id); .FirstOrDefault(t => t.Id == id);
@ -60,7 +60,7 @@ namespace Volo.Abp.TenantManagement.MongoDB
.ToListAsync(GetCancellationToken(cancellationToken)); .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() return await GetMongoQueryable()
.WhereIf<Tenant, IMongoQueryable<Tenant>>( .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(); CreateRoleMappings();
} }
private void CreateRoleMappings() protected virtual void CreateRoleMappings()
{ {
//List //List
CreateMap<TenantDto, EditModalModel.TenantInfoModel>(); 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 class AbpTenantManagementWebMainMenuContributor : IMenuContributor
{ {
public async Task ConfigureMenuAsync(MenuConfigurationContext context) public virtual async Task ConfigureMenuAsync(MenuConfigurationContext context)
{ {
if (context.Menu.Name != StandardMenus.Main) 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] [BindProperty]
public TenantInfoModel Tenant { get; set; } public TenantInfoModel Tenant { get; set; }
private readonly ITenantAppService _tenantAppService; protected ITenantAppService TenantAppService { get; }
public ConnectionStringsModal(ITenantAppService tenantAppService) 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 Tenant = new TenantInfoModel
{ {
Id = id, 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(); ValidateModel();
if (Tenant.UseSharedDatabase || Tenant.DefaultConnectionString.IsNullOrWhiteSpace()) if (Tenant.UseSharedDatabase || Tenant.DefaultConnectionString.IsNullOrWhiteSpace())
{ {
await _tenantAppService.DeleteDefaultConnectionStringAsync(Tenant.Id); await TenantAppService.DeleteDefaultConnectionStringAsync(Tenant.Id);
} }
else else
{ {
await _tenantAppService.UpdateDefaultConnectionStringAsync(Tenant.Id, Tenant.DefaultConnectionString); await TenantAppService.UpdateDefaultConnectionStringAsync(Tenant.Id, Tenant.DefaultConnectionString);
} }
return NoContent(); 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] [BindProperty]
public TenantInfoModel Tenant { get; set; } public TenantInfoModel Tenant { get; set; }
private readonly ITenantAppService _tenantAppService; protected ITenantAppService TenantAppService { get; }
public CreateModalModel(ITenantAppService tenantAppService) 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(); ValidateModel();
var input = ObjectMapper.Map<TenantInfoModel, TenantCreateDto>(Tenant); var input = ObjectMapper.Map<TenantInfoModel, TenantCreateDto>(Tenant);
await _tenantAppService.CreateAsync(input); await TenantAppService.CreateAsync(input);
return NoContent(); 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] [BindProperty]
public TenantInfoModel Tenant { get; set; } public TenantInfoModel Tenant { get; set; }
private readonly ITenantAppService _tenantAppService; protected ITenantAppService TenantAppService { get; }
public EditModalModel(ITenantAppService tenantAppService) 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>( 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(); ValidateModel();
var input = ObjectMapper.Map<TenantInfoModel, TenantUpdateDto>(Tenant); var input = ObjectMapper.Map<TenantInfoModel, TenantUpdateDto>(Tenant);
await _tenantAppService.UpdateAsync(Tenant.Id, input); await TenantAppService.UpdateAsync(Tenant.Id, input);
return NoContent(); 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; using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants
{ {
public class IndexModel : TenantManagementPageModel public class IndexModel : TenantManagementPageModel
{ {
public void OnGet() public virtual Task OnGetAsync()
{ {
return Task.CompletedTask;
}
public virtual Task OnPostAsync()
{
return Task.CompletedTask;
} }
} }
} }
Loading…
Cancel
Save