Skip to content

Commit

Permalink
Add singleton IScopeAccessor service as an abstraction over HttpContext.
Browse files Browse the repository at this point in the history
  • Loading branch information
dimarobert committed Jan 31, 2020
1 parent c0b727b commit 14190aa
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 8 deletions.
14 changes: 10 additions & 4 deletions DNN Platform/DotNetNuke.Web.Mvc/DnnMvcDependencyResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using DotNetNuke.Common.Extensions;
using DotNetNuke.Services.DependencyInjection;

namespace DotNetNuke.Web.Mvc
{
Expand All @@ -17,6 +16,11 @@ namespace DotNetNuke.Web.Mvc
/// </summary>
internal class DnnMvcDependencyResolver : IDependencyResolver
{
private readonly IServiceProvider _serviceProvider;

public DnnMvcDependencyResolver(IServiceProvider serviceProvider) {
_serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
}

/// <summary>
/// Returns the specified service from the scope
Expand All @@ -29,7 +33,8 @@ internal class DnnMvcDependencyResolver : IDependencyResolver
/// </returns>
public object GetService(Type serviceType)
{
var scope = HttpContext.Current?.GetScope();
var accessor = _serviceProvider.GetRequiredService<IScopeAccessor>();
var scope = accessor.GetScope(); // HttpContext.Current?.GetScope();
if (scope != null)
return scope.ServiceProvider.GetService(serviceType);

Expand All @@ -47,7 +52,8 @@ public object GetService(Type serviceType)
/// </returns>
public IEnumerable<object> GetServices(Type serviceType)
{
var scope = HttpContext.Current?.GetScope();
var accessor = _serviceProvider.GetRequiredService<IScopeAccessor>();
var scope = accessor.GetScope(); // HttpContext.Current?.GetScope();
if (scope != null)
return scope.ServiceProvider.GetServices(serviceType);

Expand Down
3 changes: 2 additions & 1 deletion DNN Platform/DotNetNuke.Web.Mvc/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.Extensions.DependencyInjection;
using DotNetNuke.Web.Mvc.Extensions;
using System.Web.Mvc;
using DotNetNuke.Common;

namespace DotNetNuke.Web.Mvc
{
Expand All @@ -18,7 +19,7 @@ public void ConfigureServices(IServiceCollection services)

services.AddWebApiControllers();

DependencyResolver.SetResolver(new DnnMvcDependencyResolver());
DependencyResolver.SetResolver(new DnnMvcDependencyResolver(Globals.DependencyProvider));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.Web.Http.Dependencies;
using DotNetNuke.Common.Extensions;
using DotNetNuke.Services.DependencyInjection;

namespace DotNetNuke.Web.Api.Internal
{
Expand Down Expand Up @@ -37,7 +38,8 @@ public DnnDependencyResolver(IServiceProvider serviceProvider)
/// </returns>
public IDependencyScope BeginScope()
{
var scope = System.Web.HttpContext.Current.GetScope();
var accessor = _serviceProvider.GetRequiredService<IScopeAccessor>();
var scope = accessor.GetScope(); // System.Web.HttpContext.Current.GetScope();
return new DnnDependencyResolver(scope.ServiceProvider);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ private void Application_Start(object sender, EventArgs eventArgs)
var name = Config.GetSetting("ServerName");
Globals.ServerName = String.IsNullOrEmpty(name) ? Dns.GetHostName() : name;

Globals.DependencyProvider = new LazyServiceProvider();
var startup = new Startup();
Globals.DependencyProvider = startup.DependencyProvider;
(Globals.DependencyProvider as LazyServiceProvider).SetProvider(startup.DependencyProvider);
ServiceRequestScopeModule.SetServiceProvider(Globals.DependencyProvider);

ComponentFactory.Container = new SimpleContainer();
Expand Down
26 changes: 26 additions & 0 deletions DNN Platform/DotNetNuke.Web/Common/LazyServiceProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DotNetNuke.Web.Common
{
public class LazyServiceProvider : IServiceProvider
{
private IServiceProvider _serviceProvider;

public object GetService(Type serviceType)
{
if (_serviceProvider is null)
throw new Exception("Cannot resolve services until the service provider is built.");

return _serviceProvider.GetService(serviceType);
}

internal void SetProvider(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
}
}
1 change: 1 addition & 0 deletions DNN Platform/DotNetNuke.Web/DotNetNuke.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@
<Compile Include="Common\DynamicSharedConstants.cs" />
<Compile Include="Common\DotNetNukeHttpApplication.cs" />
<Compile Include="Api\WebApiException.cs" />
<Compile Include="Common\LazyServiceProvider.cs" />
<Compile Include="Components\Controllers\ControlBarController.cs" />
<Compile Include="Components\Controllers\IControlBarController.cs" />
<Compile Include="Components\Controllers\Models\MenuItemViewModel.cs" />
Expand Down
2 changes: 2 additions & 0 deletions DNN Platform/DotNetNuke.Web/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using DotNetNuke.DependencyInjection;
using DotNetNuke.DependencyInjection.Extensions;
using DotNetNuke.Instrumentation;
using DotNetNuke.Services.DependencyInjection;
using DotNetNuke.Web.Extensions;
using Microsoft.Extensions.DependencyInjection;
using System;
Expand All @@ -25,6 +26,7 @@ public Startup()
private void Configure()
{
var services = new ServiceCollection();
services.AddSingleton<IScopeAccessor, ScopeAccessor>();
ConfigureServices(services);
DependencyProvider = services.BuildServiceProvider();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static IServiceScope GetScope(this HttpContext httpContext)
return GetScope(httpContext.Items);
}

private static IServiceScope GetScope(System.Collections.IDictionary contextItems)
internal static IServiceScope GetScope(System.Collections.IDictionary contextItems)
{
if (!contextItems.Contains(typeof(IServiceScope)))
return null;
Expand Down
1 change: 1 addition & 0 deletions DNN Platform/Library/DotNetNuke.Library.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@
<Compile Include="Services\Cryptography\CryptographyProvider.cs" />
<Compile Include="Services\Cryptography\ICryptographyProvider.cs" />
<Compile Include="Services\Authentication\UserAuthenticationInfo.cs" />
<Compile Include="Services\DependencyInjection\IScopeAccessor.cs" />
<Compile Include="Services\Exceptions\ExceptionExtensions.cs" />
<Compile Include="Services\Exceptions\SearchIndexEmptyException.cs" />
<Compile Include="Services\Assets\AssetManager.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using DotNetNuke.Common.Extensions;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace DotNetNuke.Services.DependencyInjection {
public interface IScopeAccessor {
IServiceScope GetScope();
}

public class ScopeAccessor : IScopeAccessor {
private static Func<IDictionary> fallbackGetContextItems = () => HttpContext.Current?.Items;

private Func<IDictionary> _getContextItems;

public ScopeAccessor() {
_getContextItems = fallbackGetContextItems;
}

public IServiceScope GetScope() {
return HttpContextDependencyInjectionExtensions.GetScope(_getContextItems());
}

internal void SetContextItemsFunc(Func<IDictionary> getContextItems) {
_getContextItems = getContextItems ?? fallbackGetContextItems;
}
}
}

0 comments on commit 14190aa

Please sign in to comment.