Skip to content

Commit 72ede51

Browse files
committed
Add singleton IScopeAccessor service as an abstraction over HttpContext.
1 parent c0b727b commit 72ede51

File tree

10 files changed

+84
-8
lines changed

10 files changed

+84
-8
lines changed

DNN Platform/DotNetNuke.Web.Mvc/DnnMvcDependencyResolver.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
using Microsoft.Extensions.DependencyInjection;
66
using System;
77
using System.Collections.Generic;
8-
using System.Web;
98
using System.Web.Mvc;
10-
using DotNetNuke.Common.Extensions;
9+
using DotNetNuke.Services.DependencyInjection;
1110

1211
namespace DotNetNuke.Web.Mvc
1312
{
@@ -17,6 +16,12 @@ namespace DotNetNuke.Web.Mvc
1716
/// </summary>
1817
internal class DnnMvcDependencyResolver : IDependencyResolver
1918
{
19+
private readonly IServiceProvider _serviceProvider;
20+
21+
public DnnMvcDependencyResolver(IServiceProvider serviceProvider)
22+
{
23+
_serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
24+
}
2025

2126
/// <summary>
2227
/// Returns the specified service from the scope
@@ -29,7 +34,8 @@ internal class DnnMvcDependencyResolver : IDependencyResolver
2934
/// </returns>
3035
public object GetService(Type serviceType)
3136
{
32-
var scope = HttpContext.Current?.GetScope();
37+
var accessor = _serviceProvider.GetRequiredService<IScopeAccessor>();
38+
var scope = accessor.GetScope();
3339
if (scope != null)
3440
return scope.ServiceProvider.GetService(serviceType);
3541

@@ -47,7 +53,8 @@ public object GetService(Type serviceType)
4753
/// </returns>
4854
public IEnumerable<object> GetServices(Type serviceType)
4955
{
50-
var scope = HttpContext.Current?.GetScope();
56+
var accessor = _serviceProvider.GetRequiredService<IScopeAccessor>();
57+
var scope = accessor.GetScope();
5158
if (scope != null)
5259
return scope.ServiceProvider.GetServices(serviceType);
5360

DNN Platform/DotNetNuke.Web.Mvc/Startup.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.Extensions.DependencyInjection;
77
using DotNetNuke.Web.Mvc.Extensions;
88
using System.Web.Mvc;
9+
using DotNetNuke.Common;
910

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

1920
services.AddWebApiControllers();
2021

21-
DependencyResolver.SetResolver(new DnnMvcDependencyResolver());
22+
DependencyResolver.SetResolver(new DnnMvcDependencyResolver(Globals.DependencyProvider));
2223
}
2324
}
2425
}

DNN Platform/DotNetNuke.Web/Api/Internal/DnnDependencyResolver.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Collections.Generic;
88
using System.Web.Http.Dependencies;
99
using DotNetNuke.Common.Extensions;
10+
using DotNetNuke.Services.DependencyInjection;
1011

1112
namespace DotNetNuke.Web.Api.Internal
1213
{
@@ -37,7 +38,8 @@ public DnnDependencyResolver(IServiceProvider serviceProvider)
3738
/// </returns>
3839
public IDependencyScope BeginScope()
3940
{
40-
var scope = System.Web.HttpContext.Current.GetScope();
41+
var accessor = _serviceProvider.GetRequiredService<IScopeAccessor>();
42+
var scope = accessor.GetScope();
4143
return new DnnDependencyResolver(scope.ServiceProvider);
4244
}
4345

DNN Platform/DotNetNuke.Web/Common/DotNetNukeHttpApplication.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ private void Application_Start(object sender, EventArgs eventArgs)
6767
var name = Config.GetSetting("ServerName");
6868
Globals.ServerName = String.IsNullOrEmpty(name) ? Dns.GetHostName() : name;
6969

70+
Globals.DependencyProvider = new LazyServiceProvider();
7071
var startup = new Startup();
71-
Globals.DependencyProvider = startup.DependencyProvider;
72+
(Globals.DependencyProvider as LazyServiceProvider).SetProvider(startup.DependencyProvider);
7273
ServiceRequestScopeModule.SetServiceProvider(Globals.DependencyProvider);
7374

7475
ComponentFactory.Container = new SimpleContainer();
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace DotNetNuke.Web.Common
8+
{
9+
public class LazyServiceProvider : IServiceProvider
10+
{
11+
private IServiceProvider _serviceProvider;
12+
13+
public object GetService(Type serviceType)
14+
{
15+
if (_serviceProvider is null)
16+
throw new Exception("Cannot resolve services until the service provider is built.");
17+
18+
return _serviceProvider.GetService(serviceType);
19+
}
20+
21+
internal void SetProvider(IServiceProvider serviceProvider)
22+
{
23+
_serviceProvider = serviceProvider;
24+
}
25+
}
26+
}

DNN Platform/DotNetNuke.Web/DotNetNuke.Web.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@
203203
<Compile Include="Common\DynamicSharedConstants.cs" />
204204
<Compile Include="Common\DotNetNukeHttpApplication.cs" />
205205
<Compile Include="Api\WebApiException.cs" />
206+
<Compile Include="Common\LazyServiceProvider.cs" />
206207
<Compile Include="Components\Controllers\ControlBarController.cs" />
207208
<Compile Include="Components\Controllers\IControlBarController.cs" />
208209
<Compile Include="Components\Controllers\Models\MenuItemViewModel.cs" />

DNN Platform/DotNetNuke.Web/Startup.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using DotNetNuke.DependencyInjection;
66
using DotNetNuke.DependencyInjection.Extensions;
77
using DotNetNuke.Instrumentation;
8+
using DotNetNuke.Services.DependencyInjection;
89
using DotNetNuke.Web.Extensions;
910
using Microsoft.Extensions.DependencyInjection;
1011
using System;
@@ -25,6 +26,7 @@ public Startup()
2526
private void Configure()
2627
{
2728
var services = new ServiceCollection();
29+
services.AddSingleton<IScopeAccessor, ScopeAccessor>();
2830
ConfigureServices(services);
2931
DependencyProvider = services.BuildServiceProvider();
3032
}

DNN Platform/Library/Common/Extensions/HttpContextDependencyInjectionExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static IServiceScope GetScope(this HttpContext httpContext)
3030
return GetScope(httpContext.Items);
3131
}
3232

33-
private static IServiceScope GetScope(System.Collections.IDictionary contextItems)
33+
internal static IServiceScope GetScope(System.Collections.IDictionary contextItems)
3434
{
3535
if (!contextItems.Contains(typeof(IServiceScope)))
3636
return null;

DNN Platform/Library/DotNetNuke.Library.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,7 @@
701701
<Compile Include="Services\Cryptography\CryptographyProvider.cs" />
702702
<Compile Include="Services\Cryptography\ICryptographyProvider.cs" />
703703
<Compile Include="Services\Authentication\UserAuthenticationInfo.cs" />
704+
<Compile Include="Services\DependencyInjection\IScopeAccessor.cs" />
704705
<Compile Include="Services\Exceptions\ExceptionExtensions.cs" />
705706
<Compile Include="Services\Exceptions\SearchIndexEmptyException.cs" />
706707
<Compile Include="Services\Assets\AssetManager.cs" />
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using DotNetNuke.Common.Extensions;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using System;
4+
using System.Collections;
5+
using System.Web;
6+
7+
namespace DotNetNuke.Services.DependencyInjection
8+
{
9+
public interface IScopeAccessor
10+
{
11+
IServiceScope GetScope();
12+
}
13+
14+
public class ScopeAccessor : IScopeAccessor
15+
{
16+
private static Func<IDictionary> fallbackGetContextItems = () => HttpContext.Current?.Items;
17+
18+
private Func<IDictionary> _getContextItems;
19+
20+
public ScopeAccessor()
21+
{
22+
_getContextItems = fallbackGetContextItems;
23+
}
24+
25+
public IServiceScope GetScope()
26+
{
27+
return HttpContextDependencyInjectionExtensions.GetScope(_getContextItems());
28+
}
29+
30+
internal void SetContextItemsFunc(Func<IDictionary> getContextItems)
31+
{
32+
_getContextItems = getContextItems ?? fallbackGetContextItems;
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)