Drew's Blog

The Joys of Technology Explored

November 2003 - Posts

Gotta Love Misinformed Authors Spreading FUD

eWeek's Steve Gillmor: "Can Microsoft's Longhorn Pull it Off?"

[The Scobleizer Weblog]

Ok, Scoble doesn't actually comment on the article at all. I'm taking that as a sign that he finds this article as completely ridiculous as I do. The author is so misinformed and/or confused it's pathetic. He should be fired immediately or at the very least stop covering technologies he doesn't understand. Microsoft is in no way trying to replace XSD. They have not invented a new schema language for describing the structure of XML instance documents (that's what XSD is for btw), what they've invented is a custom schema language for describing WinFS objects. That's all. In fact, the schema for describing WinFS objects is undoubtedly described by an XSD itself!

To quote the article:

“It's muddy messages like this that drive developers toward the exits.”

The messages were never muddy dude. Your the one who seems to be having a hard time wrapping your head around it. And while I understand your not alone in your confusion, you have a responsibility to be a little more informed than the average Joe if you're going to be writing articles for big names like eWeek.

So, beware the FUD people and fear not. XSD is here to stay and plays an important role in plenty of core Longhorn technologies (Indigo being the prime example).

Posted: Nov 27 2003, 03:07 AM by drub0y | with 12 comment(s)
Filed under:
ASP.NET PartialCaching Problem: A Hacked Solution

Ok, I needed to prove to myself that my theory of being able to just use the built in PartialCachingControl would work if it's constructor were just public. So, I resorted to a little hackery and fell back on our friend System.Reflection to instantiate an instance of the class. Here's what I ended up with:

// 23.5-hour cache lifetime, shared across all pages
PartialCachingAttribute cacheAttribute = new PartialCachingAttribute(84600, null, null, null, true);

PartialCachingControl cacher = (PartialCachingControl)Activator.CreateInstance(typeof(PartialCachingControl), BindingFlags.NonPublic|BindingFlags.Public
|BindingFlags.ExactBinding|BindingFlags.Instance,
null, new object[] { typeof(StandardFooterCachedInnerControl), cacheAttribute, this.ID }, CultureInfo.InvariantCulture);

this.Controls.Add(cacher);

So, this logic is in the constructor of my “outer” control which is responsible for always being in the code tree and overrides Control::OnPreRender to emit the stylesheet link in the <head> of the page it is contained on. Then, as the code demonstrates, in that “outer” controls constructor I construct an instance of the PartialCachingControl using the PartialCachingAttribute data to specify the cache rules it should follow (in my case, I just need to cache the data for 23.5 hours and want it shared across all web pages) and specify the type of my inner control (i.e. StandardFooterCachedInnerControl) that actually does the rendering when the data is not cached.

As expected, this works flawlessly. This is a good enough solution for me since I always control the servers on which my control will be installed. However, it is not guaranteed to work for anyone writing third party server controls, since they might be installed with lesser code access preventing them from being able to use reflection. I can only hope that the ASP.NET team will respond to my bug report and properly expose these currently hidden little features in Whidbey for those of us who are writing more complex controls.

Posted: Nov 26 2003, 03:52 PM by drub0y | with 81 comment(s)
Filed under:
ASP.NET PartialCaching Problem Part 2
Ian Griffiths wrote the following in the comments section of this previous post:
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.
That would totally make sense, except that the only way to get a partially cached control into the control tree is to either:
  1. 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.
  2. 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.

Posted: Nov 26 2003, 11:07 AM by drub0y | with 1 comment(s)
Filed under:
ASP.NET PartialCachingAttribute Problem

Preface: I've seen this discussed before, but haven't really found a solution through all my searching, so I'm hoping I'm just missing something.

As you may or may not know, if you're creating a server control you can enable that control to be automagically cached by the ASP.NET output caching services by applying a PartialCachingAttribute to it. Once the control is rendered it's output is cached according to the number of seconds specified by the attribute. The control will never be instantiated or called in the rendering tree again until the cache expires. Cool right? Well, it is, but the magic happening here is unfortunately not very flexible.

When a server control is added to the page's control tree, it is checked for the PartialCachingAttribute. If the attribute is present, the control is wrapped with a PartialCachingControl instance. This PartialCachingControl class acts as a proxy for the actual server control in the page's control tree. In the OnRender implementation of PartialCachingControl is where all the magic happens (actually there's a BasePartialCachingControl class under there, but for simplicity we'll ignore that). The magic is the logic I discussed in the previous paragraph:

First, the cache is checked. If the cached output is [still] available (i.e. it hasn't expired) then it is just blasted out to the Response stream and that's that. If the cached output is not available, an instance of the actual server control is created. Next, there's a really nasty internal only hack done to switch the TextWriter for the current HttpResponse object so that it's an in-memory StringWriter instead (check out HttpResponse::SwitchWriter with ILDasm). This is done so that the PartialCachingControl can take the buffer and cache it using the caching architecture before it's blasted out to the HttpResponse's stream. Once this bit of trickery is completed, the original TextWriter is replaced on the HttpResponse and normal processing continues.

Ok, so with that dissection/explanation out of the way, the real problem is this. What if my cached server control needs to perform non-render time logic? In my specific case, I always need to emit a to a stylesheet. Well, it looks like I'm SOL and can no longer use the partial caching architecture anymore.

Has anyone solved this problem elegantly? My only option now seems to be to stop using the partial caching feature and basically do all the cache work manually within my server control's Render override. :\ I'd need to sniff the HtmlTextWriter type being used for the scope of the request, instantiate my own version of it with all the proper settings over my own StreamWriter, use that to write all my content, then get the text from the underlying StreamWriter, manually stuff it in the cache and then manually blast it out to the actual response stream.

I can't understand why PartialCachingControl doesn't at least instantiate your server control and, at the bare minimum, pass on the OnInit phase of control activation. :(

Posted: Nov 25 2003, 07:40 PM by drub0y | with 3 comment(s)
Filed under:
Reusable Components: Where The Web Standards Fall Short.

From Scott Galloway:

Reading this post from Stephen Sharrock reminded me about something I often overlook, the phenomenally powerful DHTML behaviours which IE supports using HTC files. The WebService behaviour for instance lets you pull information into your client from aribtrary web services, even without using HTCs, tools like xLoadTree provide the ability to load data straight into the client without forcing a postback.
Before anyone comments, I know these are IE only - to be honest I don't care, when only
3% of users use anything other than IE, it seems a shame to ignore the functional improvements these kind of tools provide.
Now, Mozilla does support it's own version using
XBL and XUL - hopefully some genius will work out a way for mozilla to support full HTC as well...

Scott it could be a good idea to find or to create a page with all the .htc files existing around.

[help.net]

This is one of the main reasons Microsoft needed to create a technology like XAML. It drives me nuts when people ask why they didn't just use XHTML, the DOM, etc. There's zero support for re-usable component technology in those standards! Hacking together scripts that haphazzardly add behavior to existing HTML elements is the only way to do it and man it's a mess.

IE's HTC and Mozilla's XUL/XBL are awesome component technology implementations, it's just too bad there still isn't a standard. :(

Mimeo makes extensive use of DHTML for several portions of its document building process. We invented all sorts of cross-browser component technology hacks when we started, but believe me they suck compared to HTC/XUL. We're a small team, we didn't have the resources to dedicate to “best of” experiences for NS4, IE5.x+ and Mozilla 1.x at the time, so instead we had to cater to the lowest common denominator (NS4... yuck). We're getting ready to overhaul our site and bring it into the new world though, so these are both technologies we'll be spending a lot of time investigating. More difficult today though is figuring out how to write good ASP.NET server controls which emit the proper client code by detecting the browser and ultimately receive the data generated on the client back at the server side.

Part of me just wants to write it as an Avalon smart-client, but uhh... I don't think that would pull in much business over the next 4-10 years. ;)

Update: I did a little research and found some interesting stuff. It appears the HTC spec was submitted to the w3c in 1998. At that time, all the names on the spec were from Microsoft. In 1999 it looks like it became a working draft expanded to what became known as Behavioral Extensions to CSS. This document seems to spell out the specifics of how the behaviors were attached to a particular element or set of elements and even has a Netscape developer on board. This makes me wonder why work stopped there. Sure it wasn't perfect, but... it was a start. It was supported by IE. So why didn't the Mozilla people at least provide an implementation of the working draft? I understand and agree XUL/XBL is better in plenty of ways, but... at least IE already supported HTC and we could have had some form of cross-browser component technology. :(

WinFS != ObjectSpaces

In Luca Bolognese's PDC presentation on ObjectSpaces, he stated in a diagram that you should use ADO.NET's objects DataSets/DataReaders if "You require maximum control/performance/functionality" That seems to indicate that we should not use ObjectSpaces if performance, funcationality and control are a requirement.  If this is the case, it would seem that using ObjectSpaces in WinFS is very contrary.  WinFS has to be quick...not just fast...lightning fast.  We are talking about impatient users. 

I think it is important that we get Mike Deem to respond to this in his Blog.  I am going to forward this to him and post it up on the newsgroups, but maybe I am missing something. 

[Shawn Wildermuth]

It's easy to see why Shawn's concerned about this. WinFS looks so much like ObjectSpaces it's scary. However, what I think is important to realize is that the ObjectSpaces API is designed to be abstract and work over any possible datastore that might be backing your object data. The WinFS API on the other hand is designed and implemented to work with a very, very specific datastore. Truthfully we have no idea what the implementation of that datastore is, but we've been told emphatically by Microsoft reps that it is not just SQL server. With that in mind, there probably isn't much in the way of mapping/data translation as opposed to ObjectSpaces which does everything using XmlSerialization to get the data out of the object instance and ultimately into a DataSet which can then be persisted to the backing datastore.

As for the performance comments, remember ObjectSpaces is intended to be used in enterprise applications where you may be fielding 100[0]s of requests per second. With that in mind there's no doubt that using DataSets/DataReaders would be more performant since you would factor out all that mapping/translation logic. WinFS, in this first incarnation anyway, is being designed as a client technology. There is no “server story” for WinFS yet according to Microsoft reps. Considering the facts though, WinFS should theoretically outperform ObjectSpaces hands down by RTM.

Posted: Nov 23 2003, 12:56 PM by drub0y | with 2 comment(s)
Filed under: ,
Can XAML Ever Be Schema Validated? A XAML Gripe.
Alan Dean writes "the XML Schema is in the Longhorn SDK, but it "is not a totally valid schema yet, but it will become one."  [PDC Bloggers]

I'm really not sure that XAML can ever actually be pure schema validated in its current incarnation. As noted by Robert Relyea in the post, there is the conecpt of "attached" properties that are only valid in a certain context. The simplest example of this is the docking properties that get applied to child elements when you use a DockPanel. Here's a sample XAML snippet, the bold attribute is an "attached" property:

<DockPanel>
  <Border DockPanel.Dock="Top">
    <Text>This would be docked up top.</Text>
  </Border>
  <Border DockPanel.Dock="Bottom">
    <Text>This would be docked down bottom.</Text>
  </Border>
</DockPanel>

As you can see, the notation for attached properties is ParentElementName.ChildPropertyName=”Value”. There is no way in pure XML Schema to validate such context sensitive attributes today. You would need to use some sort of post schema validation architecture. A solution for DockPanel at least would be something like:

<DockPanel>
  <DockSection Location="Top">
    <Border>
      <Text>This would be docked up top.</Text>
    </Border>
  </DockSection>
  <DockSection Location="Bottom">
    <Border>
      <Text>This would be docked down bottom.</Text>
    </Border>
  </DockSection>
</DockPanel>

While I realize this appears a little more verbose, it can be validated using pure XML schema validation rules. Also, the reason I emphasized "appears" is because my samples don't even take into consideration the scenario where multiple controls are docked to the same location. At that point, each individual child control of the DockPanel requires it's own DockPanel.Dock attribute which eventually could result in more bloat than the latter approach.

Posted: Nov 03 2003, 09:11 PM by drub0y | with 10 comment(s)
Filed under:
Longhorn Already Driving Hardware Sales?

Well, for the geeks anyway. ;)

I just bought a gig of memory for my laptop so I can run and develop on the Longhorn PDC bits. Now, granted my machine would be more than enough to run a release version of Longhorn if it were released today being that it had 512 megs of memory, a DX9 GPU and a 2.8GHz processor, but something tells me it will be on the low end when Longhorn is actually released three or more years from now.

Posted: Nov 03 2003, 08:28 PM by drub0y | with 1 comment(s)
Filed under:
I've Got My Tickets, How 'Bout You?
Tickets for Matrix Revolutions that is. :)
Posted: Nov 02 2003, 11:32 PM by drub0y | with 5 comment(s)
Filed under:
More Posts