Skip to content

Commit 9ea27ad

Browse files
Merge pull request dotnet-architecture#101 from BillWagner/use-di-on-webforms-app
Use DI instead of a service locator
2 parents 0fc35d7 + a3fd171 commit 9ea27ad

5 files changed

Lines changed: 100 additions & 31 deletions

File tree

src/Web/Catalog.WebForms/Catalog.WebForms/Catalog.WebForms.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@
221221
<Compile Include="Models\CatalogItem.cs" />
222222
<Compile Include="Models\CatalogRoot.cs" />
223223
<Compile Include="Models\CatalogType.cs" />
224+
<Compile Include="Modules\AutoFacHttpModule.cs" />
224225
<Compile Include="Properties\AssemblyInfo.cs" />
225226
<Compile Include="Services\CatalogMockService.cs" />
226227
<Compile Include="Services\CatalogService.cs" />

src/Web/Catalog.WebForms/Catalog.WebForms/Default.aspx.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ public partial class _Default : Page
1818

1919
private ICatalogService catalog;
2020

21+
protected _Default() { }
22+
23+
public _Default(ICatalogService catalog)
24+
{
25+
this.catalog = catalog;
26+
}
27+
2128
protected override void OnLoad(EventArgs e)
2229
{
2330
RegisterAsyncTask(new PageAsyncTask(LoadCatalogDataAsync));
@@ -27,14 +34,9 @@ protected override void OnLoad(EventArgs e)
2734

2835
private async Task LoadCatalogDataAsync()
2936
{
30-
var container = Application.Get("container") as IContainer;
31-
using (scope = container?.BeginLifetimeScope())
32-
{
33-
catalog = container?.Resolve<ICatalogService>();
34-
var collection = await catalog?.GetCatalogAsync();
35-
catalogList.DataSource = collection;
36-
catalogList.DataBind();
37-
}
37+
var collection = await catalog?.GetCatalogAsync();
38+
catalogList.DataSource = collection;
39+
catalogList.DataBind();
3840
}
3941

4042
protected void Page_Load(object sender, EventArgs e)
Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
1-
using Autofac;
2-
using eShopOnContainers.Core.Services.Catalog;
3-
using System;
4-
using System.Collections.Generic;
5-
using System.Linq;
1+
using System;
62
using System.Web;
7-
using System.Web.Configuration;
83
using System.Web.Optimization;
94
using System.Web.Routing;
10-
using System.Web.Security;
11-
using System.Web.SessionState;
125

136
namespace Microsoft.eShopOnContainers.Catalog.WebForms
147
{
@@ -21,21 +14,6 @@ void Application_Start(object sender, EventArgs e)
2114
RouteConfig.RegisterRoutes(RouteTable.Routes);
2215
BundleConfig.RegisterBundles(BundleTable.Bundles);
2316

24-
// Register Containers:
25-
var settings= WebConfigurationManager.AppSettings;
26-
var useFake = settings["usefake"];
27-
bool fake = useFake == "true";
28-
var builder = new ContainerBuilder();
29-
if (fake)
30-
{
31-
builder.RegisterType<CatalogMockService>()
32-
.As<ICatalogService>();
33-
} else {
34-
builder.RegisterType<CatalogMockService>()
35-
.As<ICatalogService>();
36-
}
37-
var container = builder.Build();
38-
Application.Add("container", container);
3917
}
4018
}
4119
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using Autofac;
2+
using eShopOnContainers.Core.Services.Catalog;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Web;
7+
using System.Web.Configuration;
8+
using System.Web.UI;
9+
10+
namespace Microsoft.eShopOnContainers.Catalog.WebForms.Modules
11+
{
12+
// Using DI with WebForms is not yet implemented.
13+
// This implementation has been adapted from this post:
14+
// https://blogs.msdn.microsoft.com/webdev/2016/10/19/modern-asp-net-web-forms-development-dependency-injection/
15+
16+
public class AutoFacHttpModule : IHttpModule
17+
{
18+
private static IContainer Container => lazyContainer.Value;
19+
20+
private static Lazy<IContainer> lazyContainer = new Lazy<IContainer>(() => CreateContainer());
21+
22+
private static IContainer CreateContainer()
23+
{
24+
// Configure AutoFac:
25+
// Register Containers:
26+
var settings = WebConfigurationManager.AppSettings;
27+
var useFake = settings["usefake"];
28+
bool fake = useFake == "true";
29+
var builder = new ContainerBuilder();
30+
if (fake)
31+
{
32+
builder.RegisterType<CatalogMockService>()
33+
.As<ICatalogService>();
34+
}
35+
else
36+
{
37+
builder.RegisterType<CatalogMockService>()
38+
.As<ICatalogService>();
39+
}
40+
var container = builder.Build();
41+
return container;
42+
}
43+
44+
public void Dispose()
45+
{
46+
Container.Dispose();
47+
}
48+
49+
public void Init(HttpApplication context)
50+
{
51+
context.PreRequestHandlerExecute += (_, __) => InjectDependencies();
52+
}
53+
54+
private void InjectDependencies()
55+
{
56+
if (HttpContext.Current.CurrentHandler is Page)
57+
{
58+
var page = HttpContext.Current.CurrentHandler as Page;
59+
// Get the code-behind class that we may have written
60+
var pageType = page.GetType().BaseType;
61+
62+
// Determine if there is a constructor to inject, and grab it
63+
var ctor = (from c in pageType.GetConstructors()
64+
where c.GetParameters().Length > 0
65+
select c).FirstOrDefault();
66+
67+
if (ctor != null)
68+
{
69+
// Resolve the parameters for the constructor
70+
var args = (from parm in ctor.GetParameters()
71+
select Container.Resolve(parm.ParameterType))
72+
.ToArray();
73+
74+
// Execute the constructor method with the arguments resolved
75+
ctor.Invoke(page, args);
76+
}
77+
78+
// Use the Autofac method to inject any properties that can be filled by Autofac
79+
Container.InjectProperties(page);
80+
81+
}
82+
}
83+
}
84+
}

src/Web/Catalog.WebForms/Catalog.WebForms/Web.config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
</pages>
2121
<httpModules>
2222
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
23+
<!-- Use this if you are on IIS 7 and earlier -->
24+
<add name="InjectModule" type="Microsoft.eShopOnContainers.Catalog.WebForms.Modules.AutoFacHttpModule, Catalog.WebForms"/>
2325
</httpModules>
2426
</system.web>
2527
<runtime>
@@ -39,6 +41,8 @@
3941
<modules>
4042
<remove name="ApplicationInsightsWebTracking" />
4143
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
44+
<!-- Use this if you are on IIS 8 and later -->
45+
<add name="InjectModule" type="Microsoft.eShopOnContainers.Catalog.WebForms.Modules.AutoFacHttpModule, Catalog.WebForms" />
4246
</modules>
4347
</system.webServer>
4448
<system.codedom>

0 commit comments

Comments
 (0)