I am maintaining companies very old website (WebForms) and it is using Autofac as Dependency Injection.
One of the issues I have is that every time Page_Load is called, any dependencies are resolved again setting them to new. How can I stop this?
Don't have code at hand right now but this example should explain better
Example case
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
}
}
So in the above, DatabaseManager is injected into SiteSetup page. When the user selects an item in a dropdown list box 'DdlDatabase', the 'dbManager.CustomerDbConnection' is set.
If the user then clicks on a button, 'ImageSaveSite', then I get an exception when trying to access 'dbManager.CustomerDbConnection' because it is null.
Put a breakpoint in the 'Page_OnLoad' method and I can see every time it is called I can see 'dbManager.CustomerDbConnection' is null. I can only assume that a new instance of 'DatabaseManager' is being resolved.
Is there a way of preventing this? I was thinking about registering DatabaseManager as a singleton but then wouldn't every user of the website be accessing the same instance?
Because of how WebForms lifecycle works I recommend slightly different solution with use of ViewState
If you want to have some communication between postbacks you need to persist it in ViewState
. But connection is not serializable. So I used helper property ConnectionIdentifier
for keeping selected Identifier.
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
}
}