ASP.NET PartialCaching Problem Part 2
Can't you make the cached control the child of an uncached control? The uncached control wouldn't contribute anything to the output - it just wraps the cached control. That way you can put your behaviour in the uncached control, but still get caching for its child.
- Statically declare it in the ASPX. In this case when the ASPX is parsed, the parser substitues a StaticPartialCachingControl instance in place of your control and then places your custom server control in that as a child. This method won't work unless I want to force my users to declare two controls statically in their ASPX which makes no sense since this is logically one control.
- Load it using TemplateControl::LoadControl. In this case when the ASCX is parsed and loaded, the LoadControl method places the resulting custom control as the child of a PartialCachingControl instance. Obviously since I'm not an ASCX this method cannot be applied. However, as your scenario suggests, I should be able to leverage the PartialCachingControl class and add to my “outer” server control's control tree internally and then add my actual cached “inner” control to it as a child. Problem is, PartialCachingControl's only constructor is protected by assembly level access. :(
Next, I thought I could create my own custom class that inherits from BasePartialCachingControl and exposes the features that I need. Then I basically follow all the steps outlined in option 'b' using my custom partial caching control in place of PartialCachingControl and it should work. Problem solved, right? Ummm.... no. While BasePartialCachingControl is public, the method you need to override to return the server control that's wrapped when it needs to be rendered (BasePartialCachingControl::CreateCachedControl) is once again protected by assembly only level access! Bad, bad class design. I slap the ASP.NET developers on the wrist for this. There's no reason that the BasePartialCachingControl class should be public at all if one of its abstract members is marked with assembly level protection. That said, there's really no reason for that member to be marked assembly only... well... except to screw someone like me up.
So, what's left? The only thing I can think to do is manage all the cache work myself. I can create a re-usable control which follows the same wrapping pattern as the partial caching architecture does. You add controls to that re-usable control, then in the Control::Render override I setup my own HtmlTextWriter over my own StringWriter then I pass that to a call to Control::RenderChildren. When RenderChildren completes I take what it wrote through the HtmlTextWriter and stuff it into the standard caching architecture myself.
In closing, I'd just like to say that I really hate it when an API gets something just about right and forces me to re-implement all the work that they've already done, but didn't expose correctly. FYI, this hasn't been fixed in Whidbey. So, Scott, if you're listening, please just change the access level of PartialCachingControl's constructor and BasePartialCachingControl's CreateCachedControl method to public.
From: http://weblogs.asp.net/dmarsh/archive/2003/11/26/39895.aspx
浙公网安备 33010602011771号