June 2003 - Posts
Here's a little something that I term "the caching pattern" for using the ASP.NET cache object:
Object cacheItem = Cache[key] as DataTable;
if(cacheItem == null)
cacheItem = GetData();
Cache.Insert(key, cacheItem, null, DateTime.Now.AddHours(1), TimeSpan.Zero);
The as keyword will try to cast Cache[key] to DataTable and if unsuccessful it will return null. If it is null, it will return null. The rest of it is pretty straightforward. This is the best practice way to get something from the cache, but look at it! It's huge! I'm trying to come up with a helper class that will encapsulate this logic in a reusable fashion so that reading something from cache would take only a line or two of code. I'll post more when I'm done - I think I'm close to having it.
[Listening to: Queens of the Stone Age - No One Knows]
I just installed w.bloggar 3.01
and the WMPAmplog Plug-In.
Let's see how it works... I used Daniel Bright's setup instructions
to get set up in about 20 seconds. If you're reading this, everything must have worked. Ah, something for the wmpamplog FAQ - it doesn't work until you exit and restart Winamp. Pretty easy one to troubleshoot, though. Also looks like I'll have to set up my own CSS file to define class "media" for the music link...
[Listening to: Send the Pain Below - Chevelle - Wonder What's Next (04:12)]
News if you haven't heard, another application block has been released (actually a couple):
Caching Application Block (the other one is Aggregation)
I've read over the docs for the Caching block and at first glance it looks like it doesn't offer anything to ASP.NET developers that the built-in Cache API doesn't have, unless you're looking to store your cached data in a database (and suffer big perf penalties).
It's missing features that the intrinsic Cache object supports, such as providing access to the just-expired object in a CacheItemRemovedCallback (the app block only passes in the key, not the value), and it doesn't go further with than the intrinsic Cache object where the Cache object falls short (for instance, CacheItemRemovedCallback would be 1000 times more useful if it were guaranteed to complete execution BEFORE the item was actually removed from the cache. The app block might have implemented this but it doesn't appear to have).
In short, this looks like an AWESOME addition to the .NET framework for non-web developers, but it doesn't look like anything ASP.NET developers are going to be anything but underwhelmed by. By all means, tell me if I'm wrong - caching is of particular interest to me and I'd love to hear that this app block will give me things the intrinsic Cache object cannot. And perhaps, some day, when I have time, I might extend the app block to have it handle database table cache dependencies or ItemExpiredButNotYetRemovedCallbacks. But probably not; I'll just hope to see those in a future version of ASP.NET.
[Listening To: Redshift - Infamy]
Bipin Joshi interviewed me (virtually) for his website, DotNetBips.com. You may read the interview here if you're interested:
DotNetBips Inteviews Steve Smith
I've had enough people ask me for hosting advice lately to write up my thoughts in an article. You can read about my experience with the people who make up ORCSWeb in this ASPAlliance article:
Hosting Review: ORCSWeb.com
Listening To: Saliva - Rest In Pieces
There are three features I wish ASP.NET tracing had out of the box:
- Check for a null context and gracefully disable if context is null (e.g. at design time)
- If I don't specify a category, default to the name of the method in which the trace is being called.
- Automatically compile out of production code via the Conditional("DEBUG") attribute or something similar. Today, Trace routines carry overhead even when tracing is turned off.
To provide these features, I have a simple wrapper class. You can name the class itself whatever you like but I recommend it be something short so that you don't have to type much to get Tracing into your code. Feel free to use this wherever you like.
I tried to paste the code here, but the editor choked on the attributes, so go view it at ASPAlliance.com from the link below.
I'll keep this updated in article form here: Better Tracing in ASP.NET
I'm finally upgrading from OE to Outlook on the advice of Brian Tinkler of the Wisconsin .NET User Group (among many others over the past few years). The main reason that I stuck with/chose OE over Outlook was that Outlook97 didn't have an easy way to select which FROM address to use for emails, and I was frequently switching between several POP3 accounts from several organizations. OE had a nifty little dropdown, Outlook didn't. Outlook97 combined with Visual Studio 1.0 also tended to totally slow down my P2-300 laptop that I had a few years back...
So, I'm installing the Beta that came with my MSDN subscription and hoping that it is pretty stable. If not, I'll blame Brian since he told me to use it. It has a cool business contact manager thing that he says is nice, and with the amount of emails I deal with on a daily basis (and the number that have been slipping through the cracks lately), I'm hoping that helps.
Another issue that has been nagging me for some time now is spam. I've been debating signing up with a service like SpamArrest for a while now, but before shelling out money and forcing everyone I know to deal with this thing, I thought I would try another free solution that I've heard great things about, SpamBayes. Unfortunately, SpamBayes is a plugin for Outlook and wouldn't do squat with Outlook Express - another reason for me to switch.
While I'm writing about email clients, let me plug ABF Outlook Express Backup. This product rules for anybody using OE. It backs up messages, address book, favorites, rules, everything. Why OE doesn't come with such a utility is beyond me, but for $30 this thing is worth every cent. I backed up my OE stuff before beginning my Outlook upgrade and the resulting file was about 950mb. So it can definitely handle LARGE amounts of mail (can you tell I'm on a bunch of listservs and I never delete anything but spam?).
So, as you might imagine if you've done this process, with that much mail in OE, it is taking hours for Outlook to import all my stuff from OE. I have no idea how much longer it's going to take, but once I get it set up, install the business contact thingy, the spambayes thingy, and use it for a bit, I'll post back here about my experience.
[Listening To: Chevelle - Send the Pain Below]
I spoke at the Wisconsin .NET User Group last night and had a good time. A small part of my talk was on using NUnit to do unit testing and an introduction to Test Driven Development(TDD). In the course of preparing my samples I upgrade to VS.NET 2003 from VS.NET 2002 and thus from .NET v1.0 to v1.1. Unfortunately, I had a heck of a time getting NUnit to work after doing this, and was getting a security exception any time I tried to load a 1.1 compiled assembly.
There are couple of resources I was directed to related to this when I asked the community at ASPAdvice.com for help. Rachel Reese directed me to Robert McLaws blog on the subject, which in turn linked this very detailed article. However, because I'm dense at times I didn't actually "get it" as far as what I had to do until James Shaw from www.CoverYourASP.com wrote to inform me of this exact process:
To get NUnit to work with 1.1 assemblies, add this to the NUnit config files in NUnit's /bin folder (gui and console):
<supportedRuntime version="v1.1.4322" />
I did that, started up NUnit, loaded my 1.1 compiled assembly, ran my tests, and everything came up green on the first try. Yay! Hope this helps other NUnit users.
[Listening to: Redshift - Infamy (great Ohio local band)]
DonXML has a cool article I just read on how to use Attributes to extend Enums to create strongly typed parameter objects for ADO.NET commands. You can read the whole article here:
The article is cool for two reasons:
- It makes it so that adding a parameter is a very simple one line of code (not 2-3 with a bunch of parameters to mess with)
- It allows common parameters that should be the same everywhere (like, customerID) to be defined in one place. This way, you know everyone is using the same definition for the parameter, and if you switch from an int to a guid for customerID, you only have one place you need to change in your code to account for the db schema change.
[Listening To: System of a Down - Temper]
Aaron Seet posted a link to this very long and very detailed analysis of SCSI vs. IDE hard drives, which I'm posting here for others to reference and also so I know where the link is so I can finish this long article.