To answer your first Q, let me first tell you that your question itself has the answer ;). 'Shared' ... yes that's the keyword :) To have a single instance in cache for the user control across all the pages, set Shared='true' in the @OutputCache directive. This should be set at the user control level i.e. in the ascx page.
To cache the user control based on user control properties, you should specify the fully qualified name of the properties in the varyByControls section of the PartialCachingAttribute. Multiple properties if any should be separated by semi-colons.
<%@ Control Language="C#" AutoEventWireup="true"
CodeFile="WebUserControl.ascx.cs"
Inherits="UC_WebUserControl" %>
<%@ OutputCache Duration="60"
VaryByControl="UC_WebUserControl.param1;UC_WebUserControl.param2"
VaryByParam="none" Shared="true" %>
or you can also include the PartialCache attribute for the user control:
[PartialCaching(60, null, "UC_WebUserControl.param1;UC_WebUserControl.param2", null, true)]
public partial class UC_WebUserControl : System.Web.UI.UserControl
{
public string param1 { get; set; }
public string param2 { get; set; }
}
OR another way to cache the control on the combination of both values would be:
[PartialCaching(60, null, "UC_WebUserControl.BothParams", null, true)]
public partial class UC_WebUserControl : System.Web.UI.UserControl
{
public string param1 { get; set; }
public string param2 { get; set; }
public string BothParams
{
get { return String.Concat(param1, param2); }
}
}
The last parameter (true) specifies shared. Duration is specified by 60. Refer to the link How to: Cache Multiple Versions of a User Control Based on Parameters
To answer your second Q, to make the cache duration for the user control variable at run time, you can do it in two ways:
Assign it in the user control code behind:
[PartialCaching(60, null, "UC_WebUserControl.BothParams", null, true)]
public partial class WebUserControl1 : System.Web.UI.UserControl
{
...
protected void Page_Load(object sender, EventArgs e)
{
this.CachePolicy.Duration = new TimeSpan(0, 0, 60);
}
}
You can assign it in the code behind of the page where user control is referenced using the ID of the user control.
e.g. If the user control on the aspx is:
<mycontrols:control1 ID="ucControl1" runat="server" param1="15" param2="20" />
then in the code behind of aspx, you should write:
this.ucControl1.CachePolicy.Duration = new TimeSpan(0, 0, 60);
FYI, if both the user control and page are cached: If the page output cache duration is less than that of a user control, the user control will be cached until its duration has expired, even after the remainder of the page is regenerated for a request. For example, if page output caching is set to 50 seconds and the user control's output caching is set to 100 seconds, the user control expires once for every two times the rest of the page expires.