mirror of https://github.com/abpframework/abp.git
169 changed files with 1512 additions and 794 deletions
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 154 KiB |
@ -0,0 +1,40 @@ |
|||
using JetBrains.Annotations; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.AspNetCore.MultiTenancy |
|||
{ |
|||
public class HttpContextTenantResolveResultAccessor : ITenantResolveResultAccessor, ITransientDependency |
|||
{ |
|||
[CanBeNull] |
|||
public TenantResolveResult Result |
|||
{ |
|||
get |
|||
{ |
|||
if (_httpContextAccessor.HttpContext == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return _httpContextAccessor.HttpContext.Items[""] as TenantResolveResult; |
|||
} |
|||
set |
|||
{ |
|||
if (_httpContextAccessor.HttpContext == null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
_httpContextAccessor.HttpContext.Items[""] = value; |
|||
} |
|||
} |
|||
|
|||
private readonly IHttpContextAccessor _httpContextAccessor; |
|||
|
|||
public HttpContextTenantResolveResultAccessor(IHttpContextAccessor httpContextAccessor) |
|||
{ |
|||
_httpContextAccessor = httpContextAccessor; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.AspNetCore.MultiTenancy |
|||
{ |
|||
public interface ITenantResolveResultAccessor |
|||
{ |
|||
TenantResolveResult Result { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Client |
|||
{ |
|||
public class RemoteLanguageProvider : ILanguageProvider, ITransientDependency |
|||
{ |
|||
protected ICachedApplicationConfigurationClient ConfigurationClient { get; } |
|||
|
|||
public RemoteLanguageProvider(ICachedApplicationConfigurationClient configurationClient) |
|||
{ |
|||
ConfigurationClient = configurationClient; |
|||
} |
|||
|
|||
public async Task<IReadOnlyList<LanguageInfo>> GetLanguagesAsync() |
|||
{ |
|||
var configuration = await ConfigurationClient.GetAsync(); |
|||
return configuration.Localization.Languages; |
|||
} |
|||
} |
|||
} |
|||
@ -1,16 +1,21 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations |
|||
{ |
|||
[Serializable] |
|||
public class ApplicationLocalizationConfigurationDto |
|||
{ |
|||
//TODO: Rename to Texts?
|
|||
public Dictionary<string, Dictionary<string, string>> Values { get; set; } |
|||
|
|||
public List<LanguageInfo> Languages { get; set; } |
|||
|
|||
public ApplicationLocalizationConfigurationDto() |
|||
{ |
|||
Values = new Dictionary<string, Dictionary<string, string>>(); |
|||
Languages = new List<LanguageInfo>(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,17 +0,0 @@ |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Components.TenantSwitch |
|||
@model TenantSwitchViewComponent.TenantSwitchViewModel |
|||
@if (!Model.CurrentUser.IsAuthenticated) |
|||
{ |
|||
<li class="nav-item"> |
|||
<a abp-button="Link" id="TenantSwitchToolbarLink" href="#"> |
|||
@if (Model.Tenant == null) |
|||
{ |
|||
<text>@@host</text> |
|||
} |
|||
else |
|||
{ |
|||
<text>@@@Model.Tenant.Name</text> |
|||
} |
|||
</a> |
|||
</li> |
|||
} |
|||
@ -1,51 +0,0 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Components.TenantSwitch |
|||
{ |
|||
public class TenantSwitchViewComponent : AbpViewComponent |
|||
{ |
|||
/// <summary>
|
|||
/// -1,000,000
|
|||
/// </summary>
|
|||
public const int Order = -1_000_000; |
|||
|
|||
protected ITenantStore TenantStore { get; } |
|||
protected ICurrentTenant CurrentTenant { get; } |
|||
protected ICurrentUser CurrentUser { get; } |
|||
|
|||
public TenantSwitchViewComponent( |
|||
ITenantStore tenantStore, |
|||
ICurrentTenant currentTenant, |
|||
ICurrentUser currentUser) |
|||
{ |
|||
TenantStore = tenantStore; |
|||
CurrentTenant = currentTenant; |
|||
CurrentUser = currentUser; |
|||
} |
|||
|
|||
public async Task<IViewComponentResult> InvokeAsync() |
|||
{ |
|||
var model = new TenantSwitchViewModel |
|||
{ |
|||
CurrentUser = CurrentUser |
|||
}; |
|||
|
|||
if (CurrentTenant.Id.HasValue) |
|||
{ |
|||
model.Tenant = await TenantStore.FindAsync(CurrentTenant.GetId()); |
|||
} |
|||
|
|||
return View("~/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Components/TenantSwitch/Default.cshtml", model); |
|||
} |
|||
|
|||
public class TenantSwitchViewModel |
|||
{ |
|||
public TenantInfo Tenant { get; set; } |
|||
|
|||
public ICurrentUser CurrentUser { get; set; } |
|||
} |
|||
} |
|||
} |
|||
@ -1,3 +0,0 @@ |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling |
|||
@ -1,9 +1,11 @@ |
|||
{ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"GivenTenantIsNotAvailable": "Given tenant is not available: {0}", |
|||
"SwitchTenant": "Switch tenant", |
|||
"Tenant": "Tenant", |
|||
"Switch": "switch", |
|||
"Name": "Name", |
|||
"SwitchTenantHint": "Leave the name field blank to switch to the host side." |
|||
"SwitchTenantHint": "Leave the name field blank to switch to the host side.", |
|||
"NotSelected": "Not selected" |
|||
} |
|||
} |
|||
@ -1,21 +0,0 @@ |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Components.TenantSwitch; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy |
|||
{ |
|||
public class MultiTenancyToolbarContributor : IToolbarContributor |
|||
{ |
|||
public Task ConfigureToolbarAsync(IToolbarConfigurationContext context) |
|||
{ |
|||
if (context.Toolbar.Name != StandardToolbars.Main) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
context.Toolbar.Items.Add(new ToolbarItem(typeof(TenantSwitchViewComponent), TenantSwitchViewComponent.Order)); |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Data |
|||
{ |
|||
public class DataSeedContext |
|||
{ |
|||
public Guid? TenantId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets/sets a key-value on the <see cref="Properties"/>.
|
|||
/// </summary>
|
|||
/// <param name="name">Name of the property</param>
|
|||
/// <returns>
|
|||
/// Returns the value in the <see cref="Properties"/> dictionary by given <see cref="name"/>.
|
|||
/// Returns null if given <see cref="name"/> is not present in the <see cref="Properties"/> dictionary.
|
|||
/// </returns>
|
|||
[CanBeNull] |
|||
public object this[string name] |
|||
{ |
|||
get => Properties.GetOrDefault(name); |
|||
set => Properties[name] = value; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Can be used to get/set custom properties.
|
|||
/// </summary>
|
|||
[NotNull] |
|||
public Dictionary<string, object> Properties { get; } |
|||
|
|||
public DataSeedContext(Guid? tenantId = null) |
|||
{ |
|||
TenantId = tenantId; |
|||
Properties = new Dictionary<string, object>(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Sets a property in the <see cref="Properties"/> dictionary.
|
|||
/// This is a shortcut for nested calls on this object.
|
|||
/// </summary>
|
|||
public virtual DataSeedContext WithProperty(string key, object value) |
|||
{ |
|||
Properties[key] = value; |
|||
return this; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Collections; |
|||
|
|||
namespace Volo.Abp.Data |
|||
{ |
|||
public class DataSeedContributorList : TypeList<IDataSeedContributor> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
namespace Volo.Abp.Data |
|||
{ |
|||
public class DataSeedOptions |
|||
{ |
|||
public DataSeedContributorList Contributors { get; } |
|||
|
|||
public DataSeedOptions() |
|||
{ |
|||
Contributors = new DataSeedContributorList(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Data |
|||
{ |
|||
//TODO: Create a Volo.Abp.Data.Seeding namespace?
|
|||
public class DataSeeder : IDataSeeder, ITransientDependency |
|||
{ |
|||
protected IHybridServiceScopeFactory ServiceScopeFactory { get; } |
|||
protected DataSeedOptions Options { get; } |
|||
|
|||
public DataSeeder( |
|||
IOptions<DataSeedOptions> options, |
|||
IHybridServiceScopeFactory serviceScopeFactory) |
|||
{ |
|||
ServiceScopeFactory = serviceScopeFactory; |
|||
Options = options.Value; |
|||
} |
|||
|
|||
public async Task SeedAsync(DataSeedContext context) |
|||
{ |
|||
using (var scope = ServiceScopeFactory.CreateScope()) |
|||
{ |
|||
foreach (var contributorType in Options.Contributors) |
|||
{ |
|||
var contributor = (IDataSeedContributor) scope |
|||
.ServiceProvider |
|||
.GetRequiredService(contributorType); |
|||
|
|||
await contributor.SeedAsync(context); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.Abp.Data |
|||
{ |
|||
public static class DataSeederExtensions |
|||
{ |
|||
public static Task SeedAsync(this IDataSeeder seeder, Guid? tenantId = null) |
|||
{ |
|||
return seeder.SeedAsync(new DataSeedContext(tenantId)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.Abp.Data |
|||
{ |
|||
public interface IDataSeedContributor |
|||
{ |
|||
Task SeedAsync(DataSeedContext context); |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.Abp.Data |
|||
{ |
|||
public interface IDataSeeder |
|||
{ |
|||
Task SeedAsync(DataSeedContext context); |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace Volo.Abp.Localization |
|||
{ |
|||
[LocalizationResourceName("Default")] |
|||
public class DefaultResource |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -1,15 +0,0 @@ |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Security; |
|||
|
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpDataModule), |
|||
typeof(AbpSecurityModule) |
|||
)] |
|||
public class AbpMultiTenancyAbstractionsModule : AbpModule //TODO: Rename to AbpMultiTenancyModule?
|
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -1,21 +0,0 @@ |
|||
using System.Threading; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
public class AsyncLocalCurrentTenantIdAccessor : ICurrentTenantIdAccessor, ISingletonDependency |
|||
{ |
|||
public TenantIdWrapper Current |
|||
{ |
|||
get => _currentScope.Value; |
|||
set => _currentScope.Value = value; |
|||
} |
|||
|
|||
private readonly AsyncLocal<TenantIdWrapper> _currentScope; |
|||
|
|||
public AsyncLocalCurrentTenantIdAccessor() |
|||
{ |
|||
_currentScope = new AsyncLocal<TenantIdWrapper>(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,30 +0,0 @@ |
|||
using System; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.MultiTenancy.ConfigurationStore |
|||
{ |
|||
//TODO: Move to another package.
|
|||
[Dependency(TryRegister = true)] |
|||
public class ConfigurationTenantStore : ITenantStore, ITransientDependency |
|||
{ |
|||
private readonly ConfigurationTenantStoreOptions _options; |
|||
|
|||
public ConfigurationTenantStore(IOptionsSnapshot<ConfigurationTenantStoreOptions> options) |
|||
{ |
|||
_options = options.Value; |
|||
} |
|||
|
|||
public Task<TenantInfo> FindAsync(string name) |
|||
{ |
|||
return Task.FromResult(_options.Tenants.FirstOrDefault(t => t.Name == name)); |
|||
} |
|||
|
|||
public Task<TenantInfo> FindAsync(Guid id) |
|||
{ |
|||
return Task.FromResult(_options.Tenants.FirstOrDefault(t => t.Id == id)); |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +0,0 @@ |
|||
namespace Volo.Abp.MultiTenancy.ConfigurationStore |
|||
{ |
|||
public class ConfigurationTenantStoreOptions |
|||
{ |
|||
public TenantInfo[] Tenants { get; set; } |
|||
|
|||
public ConfigurationTenantStoreOptions() |
|||
{ |
|||
Tenants = new TenantInfo[0]; |
|||
} |
|||
} |
|||
} |
|||
@ -1,34 +0,0 @@ |
|||
using System; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
public class CurrentTenant : ICurrentTenant, ITransientDependency |
|||
{ |
|||
public virtual bool IsAvailable => Id.HasValue; |
|||
|
|||
public virtual Guid? Id => _currentTenantIdAccessor.Current?.TenantId; |
|||
|
|||
private readonly ICurrentTenantIdAccessor _currentTenantIdAccessor; |
|||
|
|||
public CurrentTenant(ICurrentTenantIdAccessor currentTenantIdAccessor) |
|||
{ |
|||
_currentTenantIdAccessor = currentTenantIdAccessor; |
|||
} |
|||
|
|||
public IDisposable Change(Guid? id) |
|||
{ |
|||
return SetCurrent(id); |
|||
} |
|||
|
|||
private IDisposable SetCurrent(Guid? tenantId) |
|||
{ |
|||
var parentScope = _currentTenantIdAccessor.Current; |
|||
_currentTenantIdAccessor.Current = new TenantIdWrapper(tenantId); |
|||
return new DisposeAction(() => |
|||
{ |
|||
_currentTenantIdAccessor.Current = parentScope; |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
/* Uses TenantScopeTenantInfoWrapper instead of TenantInfo because being null of Current is different that being null of Current.Tenant. |
|||
* A null Current indicates that we haven't set it explicitly. |
|||
* A null Current.Tenant indicates that we have set null tenant value explicitly. |
|||
* A non-null Current.Tenant indicates that we have set a tenant value explicitly. |
|||
*/ |
|||
|
|||
public interface ICurrentTenantIdAccessor |
|||
{ |
|||
TenantIdWrapper Current { get; set; } |
|||
} |
|||
} |
|||
@ -1,18 +0,0 @@ |
|||
using System; |
|||
|
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
public class TenantIdWrapper |
|||
{ |
|||
/// <summary>
|
|||
/// Null indicates the host.
|
|||
/// Not null value for a tenant.
|
|||
/// </summary>
|
|||
public Guid? TenantId { get; } |
|||
|
|||
public TenantIdWrapper(Guid? tenantId) |
|||
{ |
|||
TenantId = tenantId; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.MultiTenancy.ConfigurationStore; |
|||
using Volo.Abp.Security; |
|||
|
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
//TODO: Create a Volo.Abp.MultiTenancy.Abstractions package?
|
|||
|
|||
[DependsOn( |
|||
typeof(AbpDataModule), |
|||
typeof(AbpSecurityModule) |
|||
)] |
|||
public class AbpMultiTenancyModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var configuration = context.Services.GetConfiguration(); |
|||
Configure<DefaultTenantStoreOptions>(configuration); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using System.Threading; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
public class AsyncLocalCurrentTenantAccessor : ICurrentTenantAccessor, ISingletonDependency |
|||
{ |
|||
public BasicTenantInfo Current |
|||
{ |
|||
get => _currentScope.Value; |
|||
set => _currentScope.Value = value; |
|||
} |
|||
|
|||
private readonly AsyncLocal<BasicTenantInfo> _currentScope; |
|||
|
|||
public AsyncLocalCurrentTenantAccessor() |
|||
{ |
|||
_currentScope = new AsyncLocal<BasicTenantInfo>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using System; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
public class BasicTenantInfo |
|||
{ |
|||
/// <summary>
|
|||
/// Null indicates the host.
|
|||
/// Not null value for a tenant.
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
public Guid? TenantId { get; } |
|||
|
|||
/// <summary>
|
|||
/// Name of the tenant if <see cref="TenantId"/> is not null.
|
|||
/// </summary>
|
|||
[CanBeNull] |
|||
public string Name { get; } |
|||
|
|||
public BasicTenantInfo(Guid? tenantId, string name = null) |
|||
{ |
|||
TenantId = tenantId; |
|||
Name = name; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.MultiTenancy.ConfigurationStore |
|||
{ |
|||
[Dependency(TryRegister = true)] |
|||
public class DefaultTenantStore : ITenantStore, ITransientDependency |
|||
{ |
|||
private readonly DefaultTenantStoreOptions _options; |
|||
|
|||
public DefaultTenantStore(IOptionsSnapshot<DefaultTenantStoreOptions> options) |
|||
{ |
|||
_options = options.Value; |
|||
} |
|||
|
|||
public Task<TenantConfiguration> FindAsync(string name) |
|||
{ |
|||
return Task.FromResult(_options.Tenants?.FirstOrDefault(t => t.Name == name)); |
|||
} |
|||
|
|||
public Task<TenantConfiguration> FindAsync(Guid id) |
|||
{ |
|||
return Task.FromResult(_options.Tenants?.FirstOrDefault(t => t.Id == id)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
namespace Volo.Abp.MultiTenancy.ConfigurationStore |
|||
{ |
|||
public class DefaultTenantStoreOptions |
|||
{ |
|||
public TenantConfiguration[] Tenants { get; set; } |
|||
|
|||
public DefaultTenantStoreOptions() |
|||
{ |
|||
Tenants = new TenantConfiguration[0]; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using System; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
public class CurrentTenant : ICurrentTenant, ITransientDependency |
|||
{ |
|||
public virtual bool IsAvailable => Id.HasValue; |
|||
|
|||
public virtual Guid? Id => _currentTenantAccessor.Current?.TenantId; |
|||
|
|||
public string Name => _currentTenantAccessor.Current?.Name; |
|||
|
|||
private readonly ICurrentTenantAccessor _currentTenantAccessor; |
|||
|
|||
public CurrentTenant(ICurrentTenantAccessor currentTenantAccessor) |
|||
{ |
|||
_currentTenantAccessor = currentTenantAccessor; |
|||
} |
|||
|
|||
public IDisposable Change(Guid? id, string name = null) |
|||
{ |
|||
return SetCurrent(id, name); |
|||
} |
|||
|
|||
private IDisposable SetCurrent(Guid? tenantId, string name = null) |
|||
{ |
|||
var parentScope = _currentTenantAccessor.Current; |
|||
_currentTenantAccessor.Current = new BasicTenantInfo(tenantId, name); |
|||
return new DisposeAction(() => |
|||
{ |
|||
_currentTenantAccessor.Current = parentScope; |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
/* A null Current indicates that we haven't set it explicitly. |
|||
* A null Current.TenantId indicates that we have set null tenant id value explicitly. |
|||
* A non-null Current.TenantId indicates that we have set a tenant id value explicitly. |
|||
*/ |
|||
|
|||
public interface ICurrentTenantAccessor |
|||
{ |
|||
BasicTenantInfo Current { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System; |
|||
|
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
[Flags] |
|||
public enum MultiTenancyDatabaseStyle |
|||
{ |
|||
Shared = 1, |
|||
PerTenant = 2, |
|||
Hybrid = Shared | PerTenant |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
public class MultiTenancyOptions |
|||
{ |
|||
/// <summary>
|
|||
/// A central point to enable/disable multi-tenancy.
|
|||
/// Default: false.
|
|||
/// </summary>
|
|||
public bool IsEnabled { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Database style for tenants.
|
|||
/// Default: <see cref="MultiTenancyDatabaseStyle.Hybrid"/>.
|
|||
/// </summary>
|
|||
public MultiTenancyDatabaseStyle DatabaseStyle { get; set; } = MultiTenancyDatabaseStyle.Hybrid; |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System; |
|||
|
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
/// <summary>
|
|||
/// Represents sides in a multi tenancy application.
|
|||
/// </summary>
|
|||
[Flags] |
|||
public enum MultiTenancySides |
|||
{ |
|||
/// <summary>
|
|||
/// Tenant side.
|
|||
/// </summary>
|
|||
Tenant = 1, |
|||
|
|||
/// <summary>
|
|||
/// Host side.
|
|||
/// </summary>
|
|||
Host = 2, |
|||
|
|||
/// <summary>
|
|||
/// Both sides
|
|||
/// </summary>
|
|||
Both = Tenant | Host |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
public abstract class TenantResolveContributorBase : ITenantResolveContributor |
|||
{ |
|||
public abstract string Name { get; } |
|||
|
|||
//TODO: We can make this async
|
|||
public abstract void Resolve(ITenantResolveContext context); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
public class TenantResolveResult |
|||
{ |
|||
public string TenantIdOrName { get; set; } |
|||
|
|||
public List<string> AppliedResolvers { get; } |
|||
|
|||
public TenantResolveResult() |
|||
{ |
|||
AppliedResolvers = new List<string>(); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue