Saturday, October 29, 2005

Great articles about Generics

Like most people, I daresay, the only way I've really been using generics over the past couple of months is for creating strongly types collections with System.Collections.Generics.List's, but I know in my heart of hearts that that's only half the story. Not even half of it. It's more like the first paragraph in the novel of Generics.

There are some great articles about generics and their use up on MSDN (Gratuitously nicked from the excellent VBFeeds.com)

Generics FAQ: Fundamentals
Generics FAQ: .NET Framework
Generics FAQ: Best Practices
Generics FAQ: Tool Support

Not just sharing, I wanted to remember them as well...

Tuesday, October 25, 2005

A grand day out. And a Grand night in!

So I spent my Saturday in the company of a whole bunch of UK nerds this weekend. And oh my, what a cool day! I've never really been to any real developer events, certainly not one that was so fiercely community driven as DeveloperDeveloperDeveloper on Saturday. And oh my what a day it was.

In keeping with my general philosophy of trying to learn new stuff that I wouldn't really have an excuse to get to know about otherwise (i.e. pretty much avoiding anything that I'm likely to encounter in work) I saw some really great people enthusing about some really cool things.

My personal highlights included:

  • Barry Dorrans being very excited about MsBuild.
  • Liam Westley being very quick and cool about SubVersion (Despite the organisers' best efforts to kleep him off the agenda ;-))
  • Ben Lamb bubbling over with the funky new stuff headed up for C# 3.0

Those are just the ones that leap readiliy to mind. I also saw some cool stuff around the CLR in SQL Server 2005, new stuff in the System.XML namespace and many many more.

It was also just really cool to see so many people there, all of whom sort of share a bit of an interest. I've discovered through my travels in the world of the fledgling developer that it's something of a solitary path to tread. Thanls to all the organisers and attendees who made it such a fun day out. No doubt I'll be at the next one.

And then, to cap it all, got home from Reading only to find that Mrs Mawoo had organised a surprise birthday party for me, so there was much beer, merriment and general fun afterwards as well (although I'm ashamed to say I was the first to leave the party. Sat down for 5 minutes, and all of a sudden all of my friends had gone and Mrs Mawoo was waking me up to put my PJ's on. That's what you get for going out all day then trying to party after!)

And last but not least, a big thanks to John who let me scrounge a ride from my house to Reading. And back. Eventually!

That's it for now. No doubt there'll be more coming. I've got a bunch of tech stuff in my head just dying to come out, but so little time to actually write it! Damned commute! Gah!

Just wanted to share.

Sunday, October 02, 2005

Non Smokers look away now...

I know it's a particularly anti-social habit, as well as being about the least politically correct thing one can do, but I am a smoker.

Even worse, I don't even have the decency to be a victime of smoking. I dont't smoke 'Because I Can't Help It' or 'Because I need to' or any ligitimate reason like that.

I smoke because, bad as it is, and an unpopular an opinion as it is, I actually enjoy it. Every cigarette is as good as the last, and so on and so forth.

I smoke for the same reason some people eat chocolate. It's nice. It makes me feel good and I like it.

So I've just got one thing to say in this post. If you're a smoker, try a shisha pipe. I brought one back from my holiday in Egypt, and it's a really nice smoke. Bought back 4 flavours of tobacco, Cappucino, Pistachio, Apple and Cola (just to see what it was like). I'm working my way through my Cappucino at the minute, and it's really quite nice. Doesn't taste much like coffee, but it certainly has something about it that's coffee-esque.

Really quite nice. And smoing a shisha's very nice as well. I heartily recommend it.

Apologies for irrelevance, political incorrectness and bad-for-your-healthness.

Saturday, September 24, 2005

Debugging and testing serviced components

I've been working over the past couple of weeks on a new data access component at work. For many and varied reasons I decided to implement it as a serviced component. I wanted to take advantage of COM+'s ability to pool and maintain objects, as well as its tried and tested transaction management capabilities for slinging stuff in and out of a SQL Server database.

Since we're using VS 2005 to develop this new project, I wanted to take advantage of the integrated Unit Testing tools that come with it straight out of the box to make sure my component was working as expected. It was here that I encountered one or two things that I'm noting here so I can remember them:

You'll never get good code coverage stats
One of the things that needs to be configured when you enable Code Coverage in VS 2005 is exactly which DLL's it's going to create code coverage stats for.

Unfortnately there are 2 things that prevent VS from allowing it for DLL's that contain serviced components.

  • COM+ only looks in the GAC

If you want COM+ to recognise your component and run it as a server component (as opposed to a library component - more in that in a minute) you must install it in the GAC. This is no biggie. You just open up you WINDOWS/Assembly folder and drag/drop your DLL into it. Job done (thanks to the Fusion shell extension). You can also use GACUTIL.exe, but isn't dragging and dropping so much easier?

So you've got you component installed in the GAC, you then need to register it as a serviced component. Easy. Just use REGSVC.exe and bob's your uncle. One serviced component, configurable through the Component Services management utility. Cool.

The problem arises, however, when you try to set up code coverage to get stats on your component. You can only reference DLL files directly, and by default the 'Select Artifacts to Instrument' dialog only incldes those DLL's in your solution.

You can add other DLL's to the list, but try to navigate to the GAC and add them from there, and no dice. It somply won't allow you. This is either an intentional feature, or a side-effect of Fusion. Although in real life, the GAC is organised as a bunch of folders with subfolders and DLL files within them, when viewed in Explorer (as in, for instance, the Open File dialog) the assemblies appear as assembly objects. Since these aren't actual DLL files, the dialog won't allow you to add them.

Oh well. I'll have a play about and see if I can't work out a way around it. I've got a couple of ideas, but they all generally revolve around changing the way the component is referenced, and as such, change the overall context in which the abject will be used. Change the test environment too much from how it's actually going to be deployed, and you've negated your tests - they're no longer valid. Some (and I really do mean a very small amount) things can be changed for the purposes of testing and debugging, but not too much.

  • Serviced Components don't run in the normal application context

Actually, this isn't strictly true. Serviced components can be run inside the context of the calling application. And it's really simple to do, too. On the property sheet for the COM+ Application you've created, under the 'Activation' tab, select 'Library Application'. This will create the objects created by COM+ in the context of the calling application.

This can even be demonstrated really easily - just step through some code that calls a serviced component you've made in the debugger. If the application's running as a Server application (i.e. objects are actually created and run in dllhost.exe, rather than in the calling app) the debugger will just step over that code. Press F11 all you like, it won't do any good. Because the object isn't in the same process as the app being debugged, it won't step into it. However if you change the configuration to a Library application, you will be able to debug to your heart's content.

So what's that got to do with Code Coverage? Well, (I think) VS only produces results for code running in the TestHost process, or the ASP.NET equivalent, if you configure it that way. So, even if I did manage to add the GAC'ed DLL, my code coverage stats would be poor. UNLESS, for the purposes of testing I configured the app as a LIbrary Application.

I guess you'd only need to do it the once, though. Once you know your unit tests cover x% of your component's code, you can configure it how it'd be in production and leave it - if you're using Team System you'll be able to publish the results and keep a record of the coverage stats to take away. Nice!

Ignore the error messages
Okay. Don't ignore the error messages, just don't drill down to fixing the exact problem in the message. Because when you're working with Serviced components, you're working with (at least!) 2 sets of technology, the COM+ stuff and the .NET framework. As a result, the errors that get caught and passed between the 2 can lose a little in the translation. I had several errors crop up with null references and invalid security priviledges. They were invariably caused by either not installing the DLL in the GAC, or forgetting to register the component in the first place. Doh! Still, it took a bit of investigating, and I spent a while looking through the code trying to work out what was wrong. Guess I learnt a bit of a lesson - It's not always just about the code you've written.

Remember which actual file's being loaded
I spent a while building, rebuilding and generally buggering about with the code the first couple of times I made significant changes to how the component worked. Either I spotted a mistake and corrected it, or I got rid of a method, or I added a method and tried to call it. Some of the corrections got me all confused since I'd made various changes to the behaviour, but the results weren't changing.

Or, I'd add a method, write some code to call it, and then get a Mising Method exception.

What was going on? It's obvious now that I've spotted it, and it's even more obvious after what you've just read about Unit Testing, but the wierdness was being caused by the DLL not being re-installed in the GAC. I'd rebuild, and then when the test app called that assembly, it wasn't the fresh up-to-date assembly being called. It was the assembly that I'd already identitfied as being wrong that was running.

Doh!

All in all, though, everything seems to be working nicely now, though. I just wanted to get some stuff to remember written down to help me remember it.

Jurt a quick plea for help, I wrote this pretty much off the top of my head. If anyone spots anything that's very incorrect, please drop a comment and let me know. Just to re-iterate, I certainly wouldn't take this post as gospel. They're just some things I wanted to make a note of, and generally thought I'd share.

Sunday, September 18, 2005

And... Breathe...

So I've been a bit busy over the past couple of weeks.

What have I been up to?

  1. Spent 2 weeks in Egypt
  2. Spent a week at work
  3. Went book shopping


Actually, that doesn't sound too busy at all. How come I feel like I haven't had 2 seeconds to sit and do anything? Oh well.

Doing some interesting stuff at the moment with System.EnterpriseServices and .NET remoting in C# 2.0. It's big fun, and if it all works, should make my life at work a bit easier. Nothing huge, but I'm currently replacing a web service with a remotable serviced component. The web service works fine, but because of the job it does, it needs to be as quick as possible. WebServices are great for a whole host of reasons, but for out purposes it could be better. It's a logging component for our intranet, which can be called across sites, but always to and from applications we've written.

There's no need for it to be interoparable over multiple environments (one of the biggest advantages of WebServices). As a result, one of the first advantages remoting has over WebServices is being able to send messages over TCP, and serialized using .NET's BinaryFormatter. This makes the messages going backwards and forwards much smaller. I haven't get any data on actual message size, but it took approximately 8 times as long to pull a dataset out through the webservice than it did to pull the same data out as business objects through a remoted component.

Add to that the nice things that COM+ brings to the table like JIT Activation, transaction management and object pooling and it should be a nice replacement.

And I get to play with C# and VS 2005.

What more could a boy want?

I'm sure I'll be writing more about my adventures in C# 2.0 shortly, but for now, I've got a couple of new books to read (this, this and this).

Just wanted to share.

Saturday, September 03, 2005

Very Very Quick...

...Before Mrs Mawoo finds me...

I'm currently blogging from a hotel lobby in Luxor, just about half way down the east coast of Egypt. I'll write more when I get back in a week or so, but here's a summary:

  • Egypt rocks.
  • Luxor rocks.
  • Aswan rocks
  • Pyramids rule.
  • Temples kick arse
  • The desert's ace
  • You can have too much of a train trip
  • Cairo doesn't rock.

I'll elaborate further when I've re-learnt how to type (funny how you can get out of practice with these things ;-)) But for now, I'm in Egypt. And that's cool.

Just wanted to share. I'm sure one day I'll get onto some .net stuff again one day...

Sunday, August 21, 2005

The perils of stubbing out methods

I only have a single-thread brain. Sad, but true. I can only really concentrate on one thing at a time.

For example, when I'm writing, I like to stub out sections of code so I can some back and flesh them out when I've finished something else. Take thei example of some code in process:

Public Function GetString(AllTheString as Boolean) as String
    If AllTheString Then
        Return "You asked for all the string"
    Else
        'Add the 'Not-All-The-String' in a minute.
        'Why not make a coffee?
    End If

You get the point. I can deal with the other path the code can take at some point in time. Perhaps after a coffee. However, this approach doesn't work in SQL Server 2000. I'm sure it's well documented and whatnot, but it really did give me some grief earlier today. Take this example:

CREATE PROCEDURE ThisIsATest
    (@TestValue int)
AS

IF EXISTS(SELECT TheKey FROM TheTable WHERE TheKey = @TestValue
BEGIN
    INSERT INTO AuditTable(Event, Time)
    VALUES ('This value was found: ' + @TestValue, GETDATE())
END
ELSE
BEGIN
    /*I'll worry about this part in a minute
    I quite feel like a coffee roundabout now...*/
END

Hit the 'Validate SQL' button, and it'll return an error. A nice error? A helpful error? An error that might vaguely suggest that you might have a code path that doesn't actually so anything? No. What does it come back with?

Incorrect syntax near the keyword 'END'

Pointing at the last line of the script.

Took me ages of sifting through a long SPROC before I realised that was what it was trying to tell me. Bugger. All I was trying to dso was vlidate the SQL I had writen so I could move on to the other part.

Just wanted to share. Apologies for irrelevance and brevity, but it's late. All because of this very thing!

Saturday, August 13, 2005

Firsts, firsts and more firsts...

We're just starting a new project at work for the next few months. It's a fairly standard data mangling app, retreiving deatails about people, updating them stashing them back in a database. Nothing really out of the ordinary.

Well, it would seem that my team doesn't like to do the same thing over and over again (fair enough, neither do I!) so we're going to be doing a whole bunch of stuff that none of us have ever really done before. Our next project will be:

  • Written in C#
  • v2.0
  • in VS 05 beta
  • All developed on virtual PCs
  • Managed by Team System (Also running on a virtual server)


It's times like this that I really like not being chrged for by the hour. We had a meeting yesterday where we kind of figured that we can get the data-mangling parts written relatively quickly, so we could spend a bit more time doing nice twiddly bits for the UI. Nice. So there's going to be a few AJAX-easqe bits (I'm not even going to pretend that it's a new thing, but I'd never found a library quite as nice as Michael Schwarz' AJAX.NET for making it happen). IN real life, I;m sure we could knock something very dull rogether in a few weeks, but that would be it. It would be a very boring bit of kit. Just another in a long line of data mangling applications, And if I was being charged for by the hour, I'm sure that would suffice ('I don't care how boring it is, just do it as quick and cheap as possible!').

But I'm not. And that's cool. We get to learn new stuff (none of us have written in C# before) use new things (all betas, which is why we're doing it all on VPC's) and have some real fun (if you're into that sort of thing) with it.

Nice!

Just wanted to share.

Saturday, August 06, 2005

Disaster at Benjimawoo Towers!

Of all the keys that had to stop working after my little bit of clumsiness a couple of weeks ago why did it have to be F11!

Yes, I know I can change the default key bindings, but i'm too lazy to change them from the VS defaults and reconfigure every time I rebuild.

Grr! Just wanted to share.

Friday, August 05, 2005

Short-circuiting comparisons

This was one of those things that I read about and though 'Huh. When am I ever going to use that?' Turns out it's pretty useful at times.

VB.NET can short circuit comparisons using the AndAlso an OrElse keywords.

What's short-circuiting?
Short circuiting occurs when you have multiple comparisons on a line and the outcome is known before you get to the end of the line. Take the following line of code:
If 1=2 And 3=3 Then
'Do some stuff
End If


You know after the first part (1=2) that the comparison is going to return false, but the second part is still evaluated (i.e. the machine still checks to see if 3 does in fact equal 3). However, if you were to use this:
If 1=2 AndAlso 3=3 Then
'Do some stuff
End If


The machine skips the 3=3 part of the comparison. Just ignores it. It knows that since 1!=2 the result is going to be false, so it just skips over the second part.

So?
That contrived example doesn't look too useful. However, if we look at a real world example, all becomes clear:

Dim ds as Dataset = GetMyDataset()
Dim dr as DataRow = GetMyDataSet.Tables(0).Rows(0)
If Not IsDbNull(dr("FieldName")) And dr("FieldName") > 0 Then
'Do some stuff
End If


Because we're using the normal 'And', if the value in the row specified is null, the method will throw an exception because a value of type DBNull can't be cast to an integer. Although 'Not IsDbNull(dr("FieldName"))' returns false (because it is null) the second section is still evaluated. And because it's a null value, an exception is thrown.

However, if we use AndAlso, the comparison is short-circuited and it doesn't throw an exception:

Dim ds as Dataset = GetMyDataset()
Dim dr as DataRow = GetMyDataSet.Tables(0).Rows(0)
If Not IsDbNull(dr("FieldName")) AndAlso dr("FieldName") > 0 Then
'Do some stuff
End If


Because the first part of the comparison return false, the framework knows that the overall expression is going to return false, so it doesn't bother trying to evaluate the second part, and it doesn't throw an exception.

Needless to say, OrElse works in exactly the same way, but for Or's rather than And's.

It's come in handy for me a couple of times recently, anyway.

Just wanted to share.