gpt4 book ai didi

c# - .NET 4.7.2 ASP.NET WebForms 网站中的依赖注入(inject) - 构造函数注入(inject)不起作用

转载 作者:行者123 更新时间:2023-12-02 07:25:46 24 4
gpt4 key购买 nike

我们目前正在处理一个较旧的项目(ASP.NET Web 表单网站),并尝试看看是否可以为其设置依赖项注入(inject)。

需要强调:这不是一个 Web 应用程序项目...它是较旧的类型,即网站。

它目前面向 .NET 4.7.2:

<httpRuntime targetFramework="4.7.2" />

到目前为止,我们已经包含了 NuGet 包:

<package id="Microsoft.AspNet.WebFormsDependencyInjection.Unity" version="1.0.0" targetFramework="net472" />

定义了一些虚拟接口(interface)和实现:

public interface IDependencyTest
{
string GetName();
}

public class DependencyTest : IDependencyTest
{
public string GetName()
{
return "Mwuhahaha!!!";
}
}

并在 global.asax 的 Application_Start 事件处理程序中连接 DI 容器:

void Application_Start(object sender, EventArgs e)
{
var container = this.AddUnity();

container.RegisterType<IDependencyTest, DependencyTest>();
}

已导入所需的命名空间:

<%@ Import Namespace="Microsoft.AspNet.WebFormsDependencyInjection.Unity" %>
<%@ Import Namespace="Unity" %>

创建了测试页面Teste.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Teste.aspx.cs" Inherits="Teste" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblDisplay" runat="server" Text="No luck..."></asp:Label>
</div>
</form>
</body>
</html>

后面的代码如下:

public partial class Teste : System.Web.UI.Page
{
private IDependencyTest _dependencyTest;

public Teste(IDependencyTest dependencyTest)
{
_dependencyTest = dependencyTest;
}

protected void Page_Load(object sender, EventArgs e)
{
lblDisplay.Text = _dependencyTest.GetName();
}
}

所有这些设置都将失败,但有以下异常(exception):

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\7a04dd72\81815e95\App_Web_teste.aspx.cdcab7d2.rtms4_ja.0.cs(187): error CS7036: There is no argument given that corresponds to the required formal parameter 'dependencyTest' of 'Teste.Teste(IDependencyTest)'

但是,属性注入(inject)确实有效:

using Unity.Attributes;

public partial class Teste : System.Web.UI.Page
{
[Dependency]
public IDependencyTest DependencyTest { get; set; }

protected void Page_Load(object sender, EventArgs e)
{
lblDisplay.Text = DependencyTest.GetName();
}
}

enter image description here

说实话,我真的很想使用构造函数注入(inject)...

为什么它不适合我们当前的设置?

是因为它是 ASP.NET 网站而不是 ASP.NET Web 应用程序吗?

可以采取什么措施让它在这里工作吗?

最佳答案

为什么它不适合我们当前的设置?

Asp.Net WebForms 的默认配置 System.Web.UI.Page 需要一个无参数构造函数来实例化您的页面并启动 Page Life Cycle

这就是在尝试使用构造函数依赖注入(inject)时收到此错误的原因。

error CS7036: There is no argument given that corresponds to the required formal parameter 'dependencyTest' of 'Teste.Teste(IDependencyTest)'
<小时/>

可以采取什么措施让它在这里也正常工作吗?

在 WebForms 的黄金时代,Asp.Net WebForms 的依赖注入(inject) (DI) 并不常见,因此很难在官方文档中找到相关内容。

在 StackOverflow 和 Google 上进行一些搜索后,我发现了一些有用的信息,可以帮助您解决问题。

<小时/>

直到 4.7.2 版本之前,Asp.Net WebForms 才很好地支持 DI

因此,如果您使用的版本低于 4.7.2,并且无法更新到较新的版本,则需要使用 PageHandlerFactory。由于我从未尝试过此操作,因此我更愿意为您提供我找到的两个引用文献的链接。

Why does everyone say dependency injection in ASP.NET webforms is hard when PageHandlerFactory and IHttpHandlerFactory exist?

Dependency Injection in ASP.NET Web Forms

<小时/>

如果您使用的版本高于 4.7.2,或者您可以更改为此版本。您可以使用对 DI 有更好支持的 WebForms。

Step 1 – Implement IServiceProvider. You can implement your own DI logic in it or plug in another DI framework, e.g. Unity, Ninject. The following example demonstrates injecting an ILog object through the constructor.

public class SimpleActivator : IServiceProvider
{
public object GetService(Type serviceType)
{
var ctors = serviceType.GetConstructors();
ConstructorInfo targetCtor = null;
foreach (var c in ctors)
{
var parameters = c.GetParameters();
if (parameters.Count() == 1 && parameters[0].ParameterType == typeof(ILog))
{
targetCtor = c;
break;
}
}

if(targetCtor != null)
{
return targetCtor.Invoke(new object[] { new DebuggingLoger() });
}
else
{
return Activator.CreateInstance(
serviceType,
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.CreateInstance,
null,
null,
null);
}
}
}

Step 2 – Set WebObjectActivator in Global.asax.

public class Global : System.Web.HttpApplication
{
public override void Init()
{
HttpRuntime.WebObjectActivator = new SimpleActivator();

base.Init();
}
}

Step 3 – Use Dependency Injection in your Webform page.

public partial class WebForm2 : System.Web.UI.Page
{
private ILog _log;

public WebForm2(ILog l)
{
_log = l;
}
}

您可以在此链接中查看此示例以及更多有关它的信息:https://devblogs.microsoft.com/dotnet/announcing-the-net-framework-4-7-2/

<小时/>

在我看来,如果您可以迁移到较新版本的 .NetFramework,您应该尝试实现 IServiceProvider。如果不能,那么您应该分析 PageHandlerFactory 的实现是否会在将来为您节省比实现它所花费的时间更多的时间。如果它在将来不能节省您的时间,您可以继续使用 [Dependency] 属性注入(inject)。

关于c# - .NET 4.7.2 ASP.NET WebForms 网站中的依赖注入(inject) - 构造函数注入(inject)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59177252/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com