From 5762ce58a4c486a7e5020010d4b6c5110345cf42 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Tue, 26 Jul 2022 09:41:42 -0400 Subject: [PATCH] introduce ITransientService interface for auto registration of transient services (for DBContexts and Repositories) --- Oqtane.Client/Program.cs | 1 + .../Extensions/OqtaneServiceCollectionExtensions.cs | 13 ++++++++++++- .../Modules/HtmlText/Repository/HtmlTextContext.cs | 2 +- .../HtmlText/Repository/HtmlTextRepository.cs | 4 +--- Oqtane.Server/Repository/PermissionRepository.cs | 13 +++++++------ .../External/Server/Repository/[Module]Context.cs | 2 +- .../Server/Repository/[Module]Repository.cs | 2 +- .../Modules/Templates/External/template.json | 2 +- Oqtane.Shared/Interfaces/IService.cs | 2 +- Oqtane.Shared/Interfaces/ITransientService.cs | 9 +++++++++ 10 files changed, 35 insertions(+), 15 deletions(-) create mode 100644 Oqtane.Shared/Interfaces/ITransientService.cs diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index 80c9fbab..0a327c7a 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -114,6 +114,7 @@ namespace Oqtane.Client private static void RegisterModuleServices(Assembly assembly, IServiceCollection services) { + // dynamically register module scoped services var implementationTypes = assembly.GetInterfaces(); foreach (var implementationType in implementationTypes) { diff --git a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs index e190936f..a402d890 100644 --- a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs +++ b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs @@ -250,7 +250,7 @@ namespace Microsoft.Extensions.DependencyInjection var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies(); foreach (var assembly in assemblies) { - // dynamically register module services, contexts, and repository classes + // dynamically register module scoped services (ie. client service classes) var implementationTypes = assembly.GetInterfaces(); foreach (var implementationType in implementationTypes) { @@ -261,6 +261,17 @@ namespace Microsoft.Extensions.DependencyInjection } } + // dynamically register module transient services (ie. server DBContext, repository classes) + implementationTypes = assembly.GetInterfaces(); + foreach (var implementationType in implementationTypes) + { + if (implementationType.AssemblyQualifiedName != null) + { + var serviceType = Type.GetType(implementationType.AssemblyQualifiedName.Replace(implementationType.Name, $"I{implementationType.Name}")); + services.AddScoped(serviceType ?? implementationType, implementationType); + } + } + // dynamically register hosted services var serviceTypes = assembly.GetTypes(hostedServiceType); foreach (var serviceType in serviceTypes) diff --git a/Oqtane.Server/Modules/HtmlText/Repository/HtmlTextContext.cs b/Oqtane.Server/Modules/HtmlText/Repository/HtmlTextContext.cs index e0c4c99f..97f95772 100644 --- a/Oqtane.Server/Modules/HtmlText/Repository/HtmlTextContext.cs +++ b/Oqtane.Server/Modules/HtmlText/Repository/HtmlTextContext.cs @@ -11,7 +11,7 @@ using Oqtane.Repository.Databases.Interfaces; namespace Oqtane.Modules.HtmlText.Repository { [PrivateApi("Mark HtmlText classes as private, since it's not very useful in the public docs")] - public class HtmlTextContext : DBContextBase, IService, IMultiDatabase + public class HtmlTextContext : DBContextBase, ITransientService, IMultiDatabase { public HtmlTextContext(ITenantManager tenantManager, IHttpContextAccessor httpContextAccessor) : base(tenantManager, httpContextAccessor) { } diff --git a/Oqtane.Server/Modules/HtmlText/Repository/HtmlTextRepository.cs b/Oqtane.Server/Modules/HtmlText/Repository/HtmlTextRepository.cs index 6f6d8e6d..fdd32df4 100644 --- a/Oqtane.Server/Modules/HtmlText/Repository/HtmlTextRepository.cs +++ b/Oqtane.Server/Modules/HtmlText/Repository/HtmlTextRepository.cs @@ -1,13 +1,11 @@ -using Microsoft.EntityFrameworkCore; using System.Linq; -using Oqtane.Modules.HtmlText.Models; using Oqtane.Documentation; using System.Collections.Generic; namespace Oqtane.Modules.HtmlText.Repository { [PrivateApi("Mark HtmlText classes as private, since it's not very useful in the public docs")] - public class HtmlTextRepository : IHtmlTextRepository, IService + public class HtmlTextRepository : IHtmlTextRepository, ITransientService { private readonly HtmlTextContext _db; diff --git a/Oqtane.Server/Repository/PermissionRepository.cs b/Oqtane.Server/Repository/PermissionRepository.cs index ed25969e..c76cd98e 100644 --- a/Oqtane.Server/Repository/PermissionRepository.cs +++ b/Oqtane.Server/Repository/PermissionRepository.cs @@ -8,6 +8,7 @@ using Microsoft.EntityFrameworkCore; using Oqtane.Extensions; using Oqtane.Models; using Microsoft.Extensions.Caching.Memory; +using Oqtane.Infrastructure; namespace Oqtane.Repository { @@ -16,20 +17,20 @@ namespace Oqtane.Repository private TenantDBContext _db; private readonly IRoleRepository _roles; private readonly IMemoryCache _cache; - private readonly IHttpContextAccessor _accessor; + private readonly SiteState _siteState; - public PermissionRepository(TenantDBContext context, IRoleRepository roles, IMemoryCache cache, IHttpContextAccessor accessor) + public PermissionRepository(TenantDBContext context, IRoleRepository roles, IMemoryCache cache, SiteState siteState) { _db = context; _roles = roles; _cache = cache; - _accessor = accessor; - } + _siteState = siteState; + } public IEnumerable GetPermissions(int siteId, string entityName) { - var alias = _accessor.HttpContext.GetAlias(); - if (alias != null) + var alias = _siteState?.Alias; + if (alias != null && alias.SiteId != -1) { return _cache.GetOrCreate($"permissions:{alias.SiteKey}:{entityName}", entry => { diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/[Module]Context.cs b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/[Module]Context.cs index 9e0fb3d9..44e1336b 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/[Module]Context.cs +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/[Module]Context.cs @@ -7,7 +7,7 @@ using Oqtane.Repository.Databases.Interfaces; namespace [Owner].[Module].Repository { - public class [Module]Context : DBContextBase, IService, IMultiDatabase + public class [Module]Context : DBContextBase, ITransientService, IMultiDatabase { public virtual DbSet [Module] { get; set; } diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/[Module]Repository.cs b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/[Module]Repository.cs index 238546dc..899dca19 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/[Module]Repository.cs +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/Repository/[Module]Repository.cs @@ -6,7 +6,7 @@ using [Owner].[Module].Models; namespace [Owner].[Module].Repository { - public class [Module]Repository : I[Module]Repository, IService + public class [Module]Repository : I[Module]Repository, ITransientService { private readonly [Module]Context _db; diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/template.json b/Oqtane.Server/wwwroot/Modules/Templates/External/template.json index 7b77591c..ce4e9acb 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/template.json +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/template.json @@ -1,5 +1,5 @@ { "Title": "Default Module Template", "Type": "External", - "Version": "3.0.0" + "Version": "3.1.4" } diff --git a/Oqtane.Shared/Interfaces/IService.cs b/Oqtane.Shared/Interfaces/IService.cs index ff30723a..14faf311 100644 --- a/Oqtane.Shared/Interfaces/IService.cs +++ b/Oqtane.Shared/Interfaces/IService.cs @@ -1,7 +1,7 @@ namespace Oqtane.Modules { /// - /// Empty interface used to decorate module services for auto registration + /// Empty interface used to decorate module services for auto registration as scoped /// public interface IService { diff --git a/Oqtane.Shared/Interfaces/ITransientService.cs b/Oqtane.Shared/Interfaces/ITransientService.cs new file mode 100644 index 00000000..a342b2e4 --- /dev/null +++ b/Oqtane.Shared/Interfaces/ITransientService.cs @@ -0,0 +1,9 @@ +namespace Oqtane.Modules +{ + /// + /// Empty interface used to decorate module services for auto registration as a transient + /// + public interface ITransientService + { + } +}