Reputation: 3627
I have a legacy ASP.Net Web Forms application targeting .Net 4.8 in which I would like to use dependency injection. Our engine of choice is LightInject.
With the help of this answer and the source code of ContainerServiceProvider.Cs from the Microsoft.AspNet.WebFormsDependencyInjection.Unity project, I was able to create my own IServiceProvider container for LightInject and assign it to the HttpRuntime.WebObjectActivator:
void Application_Start(object sender, EventArgs e)
{
...
// Register the service provider
ContainerServiceProvider containerServiceProvider = new ContainerServiceProvider(HttpRuntime.WebObjectActivator);
HttpRuntime.WebObjectActivator = containerServiceProvider;
// Register services used with dependency injection
var container = containerServiceProvider.Container;
container.Register<IDummyService, DummyService>();
}
I am able to register my services, and access them via HttpRuntime.WebObjectActivator.GetService()
.
However, I am yet to see constructor (or property) injection in action... When I declare an ASPX page (say About.aspx) with the following constructor, I get an error when I access the page: "'About' does not contain a constructor that takes 0 arguments"
public About(IDummyService dummy)
{
...
}
EDIT: this was because the website was targetting an older version of .Net in its config file. Retargetting 4.8 fixed this first issue.
Now the issue is different: if I debug the ContainerServiceProvider
I implemented, I can see that .Net tries to get the ASP.about_aspx
service that's defined in a temporary assembly (eg: C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/root/e15e9fc8/41270200/App_Web_cdps00j5.DLL
), which my LightInject container doesn't know.
So I'm not sure what else I have to do to have constructor injection working in my pages. I'm assuming that I have to tell LightInject that my pages are candidates for dependency injection somehow, but I have no idea on how to do that (the documentation is very scarce). Also, I'm wondering how Unity works because I couldn't see any magic in the source code of Microsoft.AspNet.WebFormsDependencyInjection.Unity apart from the implementation of the ContainerServiceProvider.cs
that I reused.
UPDATE: I have tried manually registering all the types that implement pages, but it did not work:
foreach (var assembly in BuildManager.GetReferencedAssemblies().Cast<Assembly>())
{
try
{
container.RegisterAssembly(
assembly,
() => new LightInject.PerScopeLifetime(),
(serviceType, implementingType) => serviceType.IsSubclassOf(typeof(System.Web.UI.Page)));
}
catch
{
}
}
Upvotes: 2
Views: 284