diff --git a/zero.Backoffice.UI/app/account/login.vue b/zero.Backoffice.UI/app/account/login.vue
index 7a8966f3..79063a30 100644
--- a/zero.Backoffice.UI/app/account/login.vue
+++ b/zero.Backoffice.UI/app/account/login.vue
@@ -23,7 +23,7 @@
-
+
@@ -114,7 +114,7 @@
grid-template-rows: 1fr auto;
align-items: stretch;
max-width: 100%;
- width: 520px;
+ width: 420px;
background: var(--color-box);
box-shadow: var(--shadow-short);
border-radius: var(--radius);
@@ -135,7 +135,7 @@
.app-auth-image
{
- height: 15px;
+ height: 16px;
}
.app-auth .ui-property + .ui-property
@@ -147,7 +147,13 @@
.app-auth-bottom
{
+ margin: calc(-1 * var(--padding));
margin-top: 3rem;
+ padding: var(--padding);
+ background: var(--color-box-nested);
+ border-top: 1px solid var(--color-line-onbg);
+ border-bottom-left-radius: var(--radius);
+ border-bottom-right-radius: var(--radius);
}
.app-auth .ui-message
diff --git a/zero.Core/Applications/ApplicationResolver.cs b/zero.Core/Applications/ApplicationResolver.cs
index b871060e..e920fc08 100644
--- a/zero.Core/Applications/ApplicationResolver.cs
+++ b/zero.Core/Applications/ApplicationResolver.cs
@@ -41,14 +41,15 @@ public class ApplicationResolver : IApplicationResolver
Application app;
- if (context.IsBackofficeRequest(Options.ZeroPath))
- {
- app = await ResolveFromUser(user);
- }
- else
- {
- app = await ResolveFromRequest(context);
- }
+ //if (context.IsBackofficeRequest(Options.ZeroPath))
+ //{
+ // app = await ResolveFromUser(user);
+ //}
+ //else
+ //{
+ // app = await ResolveFromRequest(context);
+ //}
+ app = await ResolveFromRequest(context);
if (app == null)
{
@@ -109,10 +110,10 @@ public class ApplicationResolver : IApplicationResolver
///
public async Task ResolveFromRequest(HttpContext context)
{
- if (Options.Applications.Count < 2)
- {
- return (await GetApplications()).FirstOrDefault();
- }
+ //if (Options.Applications.Count < 2)
+ //{
+ // return (await GetApplications()).FirstOrDefault();
+ //}
IApplicationResolverHandler handler = Handler.Get();
Application app = handler?.Resolve(context.Request, await GetApplications());
diff --git a/zero.Core/Context/ZeroContext.cs b/zero.Core/Context/ZeroContext.cs
index 5ae618ef..10d1b846 100644
--- a/zero.Core/Context/ZeroContext.cs
+++ b/zero.Core/Context/ZeroContext.cs
@@ -37,6 +37,9 @@ public class ZeroContext : IZeroContext
///
public IServiceProvider Services { get; private set; }
+ ///
+ public ZeroContextScope Scope { get; private set; }
+
protected IApplicationResolver AppResolver { get; private set; }
@@ -107,27 +110,16 @@ public class ZeroContext : IZeroContext
Application = await AppResolver.Resolve(context, BackofficeUser);
AppId = Application.Id;
+ Logger.LogDebug("Resolved {appId} for request {uri}", AppId, context.Request.Host.ToString() + context.Request.Path.Value.EnsureStartsWith('/'));
+
// set default database for document store
Store.ResolvedDatabase = Application.Database;
// set current culture
await CultureResolver.Resolve(this);
- }
-
- ///
- public void Override(Application app)
- {
- Application = app;
- AppId = app?.Id;
- Store.ResolvedDatabase = app?.Database;
- }
-
-
- ///
- public ZeroContextScope CreateScope(Application app)
- {
- return new(this, app, Application);
+ // set context scope
+ Scope = new(Store, Store.ResolvedDatabase, Application);
}
@@ -141,37 +133,69 @@ public class ZeroContext : IZeroContext
///
public void Remove() => ValueCollection.Remove();
+
+
+ ///
+ public ZeroContextScope CreateScope(Application app)
+ {
+ ApplyScope(app.Database, app);
+ return new ZeroContextScope(Store, app.Database, app, Scope, scope =>
+ {
+ Scope = scope.Previous;
+ ApplyScope(Scope.Database, Scope.Application);
+ });
+ }
+
+
+ ///
+ public ZeroContextScope CreateScope(string database)
+ {
+ ApplyScope(database);
+ return new ZeroContextScope(Store, database, null, Scope, scope =>
+ {
+ Scope = scope.Previous;
+ ApplyScope(Scope.Database, Scope.Application);
+ });
+ }
+
+
+ ///
+ /// Apply a database scope
+ ///
+ void ApplyScope(string database, Application app = null)
+ {
+ Application = app;
+ AppId = app?.Id;
+ Store.ResolvedDatabase = database;
+ }
}
public class ZeroContextScope : IDisposable
{
- public IZeroContext Context { get; }
-
- public Application App { get; set; }
-
- public string Database { get; set; }
+ public ZeroContextScope(IZeroStore store, string database, Application application, ZeroContextScope previous = null, Action onDispose = null)
+ {
+ Store = store;
+ Database = database;
+ Application = application;
+ Previous = previous;
+ _onDispose = onDispose;
+ }
public IZeroStore Store { get; set; }
- readonly Application _originalApp = null;
+ public Application Application { get; private set; }
+ public string Database { get; private set; }
- internal ZeroContextScope(IZeroContext context, Application app, Application originalApp)
- {
- Context = context;
- App = app;
- Database = app.Database;
- Store = context.Store;
- _originalApp = originalApp;
- Context.Override(app);
- }
+ public ZeroContextScope Previous { get; private set; }
+
+ Action _onDispose = null;
- ///
public void Dispose()
{
- Context.Override(_originalApp);
+ _onDispose?.Invoke(this);
}
}
@@ -219,6 +243,11 @@ public interface IZeroContext
///
IServiceProvider Services { get; }
+ ///
+ /// Current context scope
+ ///
+ ZeroContextScope Scope { get; }
+
///
/// Matching (frontend) path route
///
@@ -235,16 +264,6 @@ public interface IZeroContext
///
Task Resolve(HttpContext context);
- ///
- /// Overrides the resolved application for this context instance
- ///
- void Override(Application app);
-
- ///
- /// SCOPE
- ///
- ZeroContextScope CreateScope(Application app);
-
///
/// Get a custom property from this scoped context
///
@@ -259,4 +278,14 @@ public interface IZeroContext
/// Remove a custom property from this scoped context
///
void Remove();
+
+ ///
+ /// Scope the current context to a specific application database
+ ///
+ ZeroContextScope CreateScope(Application app);
+
+ ///
+ /// Scope the current context to a specific database
+ ///
+ ZeroContextScope CreateScope(string database);
}
\ No newline at end of file
diff --git a/zero.Core/Routing/RouteBulkRefresher.cs b/zero.Core/Routing/RouteBulkRefresher.cs
index 6684b957..dbc2ebce 100644
--- a/zero.Core/Routing/RouteBulkRefresher.cs
+++ b/zero.Core/Routing/RouteBulkRefresher.cs
@@ -33,7 +33,7 @@ public class RouteBulkRefresher
await scope.Store.Raven.PurgeAsync(scope.Database);
- RoutingContext context = new(scope.Store, scope.Context, session);
+ RoutingContext context = new(scope.Store, Context, session);
foreach (IRouteProvider provider in Providers.OrderByDescending(x => x.Priority))
{
diff --git a/zero.Core/Stores/StoreOperations.cs b/zero.Core/Stores/StoreOperations.cs
index dc6800e2..7ae76b9b 100644
--- a/zero.Core/Stores/StoreOperations.cs
+++ b/zero.Core/Stores/StoreOperations.cs
@@ -10,11 +10,11 @@ public partial class StoreOperations : IStoreOperations
///
public IZeroDocumentSession Session => Context.Store.Session();
- protected record EntityCollectionOptions(bool IncludeInactive);
+ protected record OperationOptions(bool IncludeInactive);
protected IZeroContext Context { get; private set; }
- protected EntityCollectionOptions Options { get; set; }
+ protected OperationOptions Options { get; set; }
protected IInterceptors Interceptors { get; private set; }
diff --git a/zero.Demo/DevApplicationResolverHandler.cs b/zero.Demo/DevApplicationResolverHandler.cs
index 5f588e4d..f69ed5ea 100644
--- a/zero.Demo/DevApplicationResolverHandler.cs
+++ b/zero.Demo/DevApplicationResolverHandler.cs
@@ -9,6 +9,7 @@ public class DevApplicationResolverHandler : IApplicationResolverHandler
static Dictionary PortMap = new()
{
{ 2310, "app.hofbauer" },
+ { 2100, "app.hofbauer" },
{ 2300, "app.brothers" },
{ 2320, "app.sporthuber" }
};
@@ -21,8 +22,6 @@ public class DevApplicationResolverHandler : IApplicationResolverHandler
public Application Resolve(HttpRequest request, IEnumerable applications)
{
- return applications.First(x => x.Id == "app.hofbauer");
-
//if (!Env.IsDevelopment())
//{
// return null;
diff --git a/zero.Demo/TestController.cs b/zero.Demo/TestController.cs
new file mode 100644
index 00000000..1976b7ca
--- /dev/null
+++ b/zero.Demo/TestController.cs
@@ -0,0 +1,41 @@
+using Microsoft.AspNetCore.Mvc;
+using zero.Context;
+using zero.Identity;
+using zero.Stores;
+
+namespace zero.Demo.Controllers;
+
+public class TestController : Controller
+{
+ [HttpGet]
+ public async Task Scoping([FromServices] IZeroContext ctx, [FromServices] IStoreOperations ops)
+ {
+ string scopeA = null;
+ string scopeB = null;
+ string scopeC = null;
+ List usersA = new();
+ List usersB = new();
+
+ scopeA = ctx.Store.ResolvedDatabase;
+
+ using (var scope = ctx.CreateScope("laola"))
+ {
+ scopeB = ctx.Store.ResolvedDatabase;
+ usersA = await ops.LoadAll();
+ }
+
+ scopeC = ctx.Store.ResolvedDatabase;
+ usersB = await ops.LoadAll();
+
+
+
+ return Json(new
+ {
+ scopeA,
+ scopeB,
+ scopeC,
+ usersA,
+ usersB
+ });
+ }
+}
\ No newline at end of file
diff --git a/zero.Demo/appsettings.json b/zero.Demo/appsettings.json
index 1deadf15..37a3db0e 100644
--- a/zero.Demo/appsettings.json
+++ b/zero.Demo/appsettings.json
@@ -11,6 +11,7 @@
"Logging": {
"LogLevel": {
"Default": "Information",
+ "zero": "Debug",
"Microsoft.AspNetCore": "Warning"
}
},