introduce ITransientService interface for auto registration of transient services (for DBContexts and Repositories)

This commit is contained in:
Shaun Walker 2022-07-26 09:41:42 -04:00
parent e61a6df4d7
commit 5762ce58a4
10 changed files with 35 additions and 15 deletions

View File

@ -114,6 +114,7 @@ namespace Oqtane.Client
private static void RegisterModuleServices(Assembly assembly, IServiceCollection services) private static void RegisterModuleServices(Assembly assembly, IServiceCollection services)
{ {
// dynamically register module scoped services
var implementationTypes = assembly.GetInterfaces<IService>(); var implementationTypes = assembly.GetInterfaces<IService>();
foreach (var implementationType in implementationTypes) foreach (var implementationType in implementationTypes)
{ {

View File

@ -250,7 +250,7 @@ namespace Microsoft.Extensions.DependencyInjection
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies(); var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
foreach (var assembly in assemblies) 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<IService>(); var implementationTypes = assembly.GetInterfaces<IService>();
foreach (var implementationType in implementationTypes) 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<ITransientService>();
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 // dynamically register hosted services
var serviceTypes = assembly.GetTypes(hostedServiceType); var serviceTypes = assembly.GetTypes(hostedServiceType);
foreach (var serviceType in serviceTypes) foreach (var serviceType in serviceTypes)

View File

@ -11,7 +11,7 @@ using Oqtane.Repository.Databases.Interfaces;
namespace Oqtane.Modules.HtmlText.Repository namespace Oqtane.Modules.HtmlText.Repository
{ {
[PrivateApi("Mark HtmlText classes as private, since it's not very useful in the public docs")] [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) { } public HtmlTextContext(ITenantManager tenantManager, IHttpContextAccessor httpContextAccessor) : base(tenantManager, httpContextAccessor) { }

View File

@ -1,13 +1,11 @@
using Microsoft.EntityFrameworkCore;
using System.Linq; using System.Linq;
using Oqtane.Modules.HtmlText.Models;
using Oqtane.Documentation; using Oqtane.Documentation;
using System.Collections.Generic; using System.Collections.Generic;
namespace Oqtane.Modules.HtmlText.Repository namespace Oqtane.Modules.HtmlText.Repository
{ {
[PrivateApi("Mark HtmlText classes as private, since it's not very useful in the public docs")] [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; private readonly HtmlTextContext _db;

View File

@ -8,6 +8,7 @@ using Microsoft.EntityFrameworkCore;
using Oqtane.Extensions; using Oqtane.Extensions;
using Oqtane.Models; using Oqtane.Models;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Oqtane.Infrastructure;
namespace Oqtane.Repository namespace Oqtane.Repository
{ {
@ -16,20 +17,20 @@ namespace Oqtane.Repository
private TenantDBContext _db; private TenantDBContext _db;
private readonly IRoleRepository _roles; private readonly IRoleRepository _roles;
private readonly IMemoryCache _cache; 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; _db = context;
_roles = roles; _roles = roles;
_cache = cache; _cache = cache;
_accessor = accessor; _siteState = siteState;
} }
public IEnumerable<Permission> GetPermissions(int siteId, string entityName) public IEnumerable<Permission> GetPermissions(int siteId, string entityName)
{ {
var alias = _accessor.HttpContext.GetAlias(); var alias = _siteState?.Alias;
if (alias != null) if (alias != null && alias.SiteId != -1)
{ {
return _cache.GetOrCreate($"permissions:{alias.SiteKey}:{entityName}", entry => return _cache.GetOrCreate($"permissions:{alias.SiteKey}:{entityName}", entry =>
{ {

View File

@ -7,7 +7,7 @@ using Oqtane.Repository.Databases.Interfaces;
namespace [Owner].[Module].Repository namespace [Owner].[Module].Repository
{ {
public class [Module]Context : DBContextBase, IService, IMultiDatabase public class [Module]Context : DBContextBase, ITransientService, IMultiDatabase
{ {
public virtual DbSet<Models.[Module]> [Module] { get; set; } public virtual DbSet<Models.[Module]> [Module] { get; set; }

View File

@ -6,7 +6,7 @@ using [Owner].[Module].Models;
namespace [Owner].[Module].Repository 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; private readonly [Module]Context _db;

View File

@ -1,5 +1,5 @@
{ {
"Title": "Default Module Template", "Title": "Default Module Template",
"Type": "External", "Type": "External",
"Version": "3.0.0" "Version": "3.1.4"
} }

View File

@ -1,7 +1,7 @@
namespace Oqtane.Modules namespace Oqtane.Modules
{ {
/// <summary> /// <summary>
/// Empty interface used to decorate module services for auto registration /// Empty interface used to decorate module services for auto registration as scoped
/// </summary> /// </summary>
public interface IService public interface IService
{ {

View File

@ -0,0 +1,9 @@
namespace Oqtane.Modules
{
/// <summary>
/// Empty interface used to decorate module services for auto registration as a transient
/// </summary>
public interface ITransientService
{
}
}