BlazorTenant 0.1.0
See the version list below for details.
dotnet add package BlazorTenant --version 0.1.0
NuGet\Install-Package BlazorTenant -Version 0.1.0
<PackageReference Include="BlazorTenant" Version="0.1.0" />
paket add BlazorTenant --version 0.1.0
#r "nuget: BlazorTenant, 0.1.0"
// Install BlazorTenant as a Cake Addin #addin nuget:?package=BlazorTenant&version=0.1.0 // Install BlazorTenant as a Cake Tool #tool nuget:?package=BlazorTenant&version=0.1.0
BlazorTenant
Support multi-tenantancy in your Blazor application. You don't need to deploy multiple versions, just load a different config based on the url.
Tested and supported
- Tenant identification from url (/TENANT/counter)
- Change authentication based on tenant
- Custom properties on the tenant to do... anything! (custom endpoints, custom tokens, feature flags, be creative!)
How does it work?
Setup is pretty simple, especially if starting with a new project. There are 3 main areas to look at. They instructures below are for WebAssembly.
Program.cs
Wire up the library to do it's thing. You will be creating a TenantStore
(library comes included with an InMemoryTenantStore
, but you can create your own) and adding that to the ServiceCollection
.
using BlazorTenant;
...
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
// Create a TenantStore
var store = new InMemoryTenantStore();
// Add manually
store.TryAdd(new Tenant("mycompany1", new Dictionary<string, string>()
{
"Property1", "value1"
}));
// Add from appsettings.json file
var tenantSection = builder.Configuration.GetSection("Tenants");
foreach(var tenant in tenantSection.GetChildren())
{
store.TryAdd(new Tenant(tenant.GetValue<string>("Identifier"), new Dictionary<string, string>()
{
"Property1", tenant.GetValue<string>("Property1")
}));
}
// Add MultiTenantancy
builder.Services.AddMultiTenantancy(store);
var build = builder.Build();
// We need the service provider for some fancy action
build.Services.AddServiceProviderToMultiTenantRoutes();
await build.RunAsync();
}
App.razor
Replace your Router
with our new MultiTenantRouter
. There is also a new RenderFragment
called NoTenant
to let you display custom messages if the tenant does not exist.
<MultiTenantRouter AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
<NoTenant Context="message">
<LayoutView Layout="@typeof(MainLayout)">
<p>@message</p>
</LayoutView>
</NoTenant>
</MultiTenantRouter>
Update your NavigationManager
This one can be a little annoying and I plan to fix in the future. When you use NavigationManager
, you will need to include the current Tenant.Identifier
so that the router works. Next step would be to replace the NavigationManager
with a TenantNavigationManager
that does this for you. But for now, you will have to do the following on your Razor pages
@inject Tenant tenant
@inject NavigationManager navigationManager
<button @onclick="GoToPage">Go!</button>
@code {
public void GoToPage()
{
navigationManager.NavigateTo($"{tenant.Identifier}/mypage");
}
}
Feel free to look at the sample project as well.
Why was this built?
Where I worked, I wanted to build a blazor app that sat on top of a few different systems. Based on your tenant, you could have a different OIDC provider, maybe a different endpoint for your data, and even some features weren't available based on where you lived. The goal of this application was to just build a new front end on existing APIs, using Blazor WebAssembly. Oh, and it had to be a PWA.
Few problems with having different tenants in Blazor
- How do you configure different OIDC paths, client ID, etc
- How do you handle different endpoints for you data?
- Yes, a lot of this data can be stored in
appsettings.json
, but this can have integrity checks so I can't make it dynamic easily - I want to run this in S3 without ANY servers... so I'm relying on just my files to be correct, no fancy tricks
A lot of inspiration was taken from Finbuckle.MultiTenant. Recently, they appear to have started supporting Blazor, but not WebAssembly (from what I can tell, please correct me). My goal was to have a completely offline solution, so I didn't want to use Blazor Server or something else.
I was learning Blazor for the first time while building this, but it helped me learn the project very quickly. This library will probably evolve over time as I learn more, but I'm very happy with the outcome in our application.
Future Plans
[ ] Build a TenantNavigationManager
[ ] Try to make ServiceProvider
not included
[ ] Make an API based TenantStore
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Microsoft.AspNetCore.Components (>= 3.1.4)
- Microsoft.AspNetCore.Components.Web (>= 3.1.3)
- Microsoft.AspNetCore.Components.WebAssembly (>= 3.2.0)
- Microsoft.AspNetCore.Components.WebAssembly.Authentication (>= 3.2.0)
- Microsoft.Extensions.Configuration (>= 3.1.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on BlazorTenant:
Repository | Stars |
---|---|
simpleidserver/SimpleIdServer
OpenID, OAuth 2.0, SCIM2.0, UMA2.0, FAPI, CIBA & OPENBANKING Framework for ASP.NET Core
|