【问题标题】:Autofac Webforms is there away to ignore postback dependency injectionAutofac Webforms 可以忽略回发依赖注入
【发布时间】:2021-01-13 11:37:39
【问题描述】:

我正在维护公司非常旧的网站 (WebForms),它使用 Autofac 作为依赖注入。

我遇到的一个问题是,每次调用 Page_Load 时,都会再次解决任何依赖关系,并将它们设置为新的。我怎样才能阻止这种情况?

目前手头没有代码,但这个例子应该能更好地解释

示例案例

public class DatabaseManager
{
    public string CustomerDbConnection {get;set;}
}

public partial class SiteSetup: Page
{
    public DatabaseManager dbManager {get;set;}

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
           // blah blah
        }

    }

    protected void DdlDatabase_SelectedIndexChanged(object sender, EventArgs e)
    {
        dbManager.CustomerDbConnection  = "Some db connection";
    }

    protected void ImageSaveSite_Click(object sender, EventArgs e)
    {
       // Do something with dbManager.CustomerDbConnection
    }
}

所以在上面,DatabaseManager 被注入到 SiteSetup 页面中。当用户在下拉列表框“DdlDatabase”中选择一个项目时,会设置“dbManager.CustomerDbConnection”。

如果用户随后单击按钮“ImageSaveSite”,则在尝试访问“dbManager.CustomerDbConnection”时出现异常,因为它为空。

在“Page_OnLoad”方法中放置一个断点,我可以看到每次调用它时我都可以看到“dbManager.CustomerDbConnection”为空。我只能假设正在解析“DatabaseManager”的新实例。

有没有办法防止这种情况发生?我正在考虑将 DatabaseManager 注册为单例,但是网站的每个用户不会访问同一个实例吗?

【问题讨论】:

    标签: c# asp.net webforms autofac


    【解决方案1】:

    由于 WebForms 生命周期的工作原理,我推荐使用 ViewState 的稍微不同的解决方案

    如果您想在回发之间进行一些通信,您需要将其保存在ViewState。但是连接是不可序列化的。所以我使用辅助属性ConnectionIdentifier 来保留选定的标识符。

    public string ConnectionIdentifier
    {
         get => ViewState[nameof(ConnectionIdentifier)] as string;
         set => ViewState[nameof(ConnectionIdentifier)] = value;
    }
    
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
           // blah blah
        }       
    }
    
    protected void DdlDatabase_SelectedIndexChanged(object sender, EventArgs e)
    {
        ConnectionIdentifier = "Selected db identifier";
    }
    
    protected void ImageSaveSite_Click(object sender, EventArgs e)
    {
        if(ConnectionIdentifier != null){
            //not really needed depending on your UI
    
            dbManager.CustomerDbConnection = ConnectionIdentifier; //processing identifier
        }
       
    }
    

    【讨论】:

    • 嗯,这是值得考虑的事情。 DatabaseManager 比我提供的要复杂得多,所以不确定我能在多大程度上转换为使用 ViewState。假设另一个选项是从 DatabaseManager 中剥离所有方法并移至单独的类。
    • @Gaz83 是的,问题是您在不同的回发事件中真正需要初始化多少。维持“状态”总是很困难的。无论应用技术如何。
    • 嗯,基本上有 12 个不同的数据库。 1 用于主网站,其余为客户数据库。通过主网站,您可以与各种客户数据库进行交互。大多数页面您必须从显示其余页面控件的下拉列表中选择一个数据库。记住这里选择的连接是关键。它似乎存储在数据库管理器中。这种使用是静态的,但会导致其他问题。我可能不得不重新考虑数据库管理器。
    • @Gaz83 这个选定的数据库有一些标识符可以在 ViewState 中使用和存储?然后用于初始化。
    • 是的,我就是这么想的。连接字符串可以进入视图状态
    猜你喜欢
    • 2012-02-15
    • 2016-11-09
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 2014-11-10
    • 2017-11-07
    • 2020-03-18
    • 1970-01-01
    相关资源
    最近更新 更多