Monday, July 02, 2007
Monday, July 02, 2007 11:15:59 AM (SE Asia Standard Time, UTC+07:00) (General)

It's enough to be trying hard to keep up with all there is to read and do these days. The last thing I want in the middle of an engaging and important read - is to be thwarted by an Adobe update. I still love Photoshop, and I'd love to love Adobe as well - but their automatic software updating process is a nightmare. I've had several bad experiences in the past and yet another today...

I was about half way through reading a PDF document - when I noticed the insidious little updater icon appear in my system tray. I ONLY have the 8.0 PDF reader installed and I foolishly thought - surely just updating my reader won't be a problem. Ouch.

First I needed to close my article. Ok - my fault for not finishing it first - but I thought I'd be right back. The updater claimed it was 0% complete when I had just received a message saying that my updates were downloaded and ready for installation. The UI and notifications we so bad that I thought I was done - and so I reopened my PDF. Something died and I got an Adobe application ending error. Then the installer came back to life and I got a new Adobe Reader icon on my desktop and a message telling me to restart my PC. WTF? I'm just updating the Adobe reader right? Not reinstalling the OS! I'm now completely out of the flow of the PDF I was reading and swearing at Adobe as I restart my PC.

On restart I notice for the first time that scrolling an eleven page document in Adobe Reader is incredibly slow and unresponsive - it's not keeping up with the mouse and this is a top spec box (5.4 on the WEI).

Adobe - what have you done? And where are you going?



| Comments [0] | | #  
Tuesday, June 12, 2007
Tuesday, June 12, 2007 10:32:29 AM (SE Asia Standard Time, UTC+07:00) (General)

From one of the net's most generous and pioneering bloggers - a great cause...



| Comments [0] | | #  
Sunday, May 13, 2007
Sunday, May 13, 2007 5:31:44 PM (SE Asia Standard Time, UTC+07:00) (Enterprise)

I wrote earlier about my experiences using the Application Block Software Factory to create a new Application Block and Provider - it started well - and creating my first provider went fine.

Putting things into production was a slightly different matter.

Again the docs are thin - and it took a brief email exchange between myself, Tom Hollander and Fernando Simonazzi of Clarius Consulting to solve one problem I came unstuck with (no doubt attributed mainly to my first crack at ObjectBuilder and ABSF).

The problem I ran into relates to the ProviderData classes that are created by the ABSF. ProviderData classes are created for each of your providers and contain the configuration information required for your provider (read from the .config file). ABSF will also create another class in the source file for your ProviderData class - an Assembler class - ProviderAssembler. ProviderAssembler implements Object Builder's IAssembler interface and is responsible for handing back an instance of your provider, along with feeding any strongly typed settings to the constructor of your provider as required.

In broad terms - there are two ways to build classes from your application block using ObjectBuilder: IAssembler or using ObjectBuilder's generic CustomProviderAssembler method.

It's not immediately obvious that there are two provider creation strategies here or that there can be issues if you mix the two.

One is strongly typed - using your own Provider Assembler class. In this case any attributes you declare in your settings file....

<add name="Provider1" type="MyProvider, ProviderProject.Providers" databaseName="Test" specialProperty="Test" />

(databaseName and specialProperty) will be referred to in your ProviderData class as properties like the following...(just the databaseName attribute here)

private const string DATABASE_NAME = "databaseName"; [ConfigurationProperty(DATABASE_NAME)] public string DatabaseName { get { return (string)this[DATABASE_NAME]; } set { this[DATABASE_NAME] = value; } }

During the call to your assembler's Assemble method - you can pass the values of these convenient and strongly typed properties into your provider's constructor.

However here's were I came unstuck.

For each of your ProviderData classes - there is also a BaseProviderData class - and at first glance this seems like correct place to place any provider properties that may be common to all your providers - with one very important exception.

The ABSF also creates a CustomProviderData class - which ALSO derives from the BaseProviderData.

CustomProviderData doesn't implement properties for configuration - it simply reads all the attributes in your settings and places them into a property bag (a name value pair collection) which will get passed into the constructor of your implemented CustomProvider. You then retrieve the settings from the NVC as you need them in your provider (casting into the required types for each attribute).

So...

<add name="Provider2" type="MyCustomProvider, ProviderProject.Providers" databaseName="Test" setting1="Test" setting2="Test" />

In this case setting1, and setting2 will appear in the NVC when received by MyCustomProvider's constructor - BUT - if the databaseName property was defined in the BaseProviderData class - it will NOT be included in the NVC. The NVC is built for 'unknown' attributes only and in the pattern of assembly provided in the ABSF - databaseName is now a 'known' configuration property (known by the BaseProviderData class) and so won't be included.

So - if you are considering offering the client the option to create their own custom providers (as opposed to pre-defined strongly typed providers in the block) - be very careful about placing common property settings in the BaseProviderData class - because if a custom provider needs an attribute of the same name - it will never see it since it won't be included in the NVC of settings during construction.



| Comments [0] | | #  
Thursday, May 10, 2007
Thursday, May 10, 2007 7:38:07 AM (SE Asia Standard Time, UTC+07:00) (Books)

I've been reading Charles' book, Appplications = Code + Markup, and spotted the flame posted by Jeff Atwood - How Not To Write a Technical Book (which I think was a bit thin all-round as a posting) where he compares Charles' book to Adam Nathan's Windows Presentation Foundation Unleashed.

Charles Petzold's book may lack a little color and design - but he's a skilled software developer and a very thoughtful author. Every code example comes with a matching source and .sln file (there are over 150 short and helpful code projects).

Charles also thought carefully about the division of the book into two halves - code and then markup - and I find it helps enormously to focus on code first - which in turn gave me a deeper understanding of what was going on in the XAML markup that followed. On Charles' own site he says openly that he wishes the design had included more screen shots - but his book is already a 976 page tour de force and frankly I'm glad it was kept as lean and clean as it is.

That said when ever I've really wanted to get a solid understanding of any topic I've usually read more than just one book - and so seeing two great books out there in two different styles can only be a good thing.



| Comments [0] | | #  
Wednesday, May 09, 2007
Wednesday, May 09, 2007 4:37:51 PM (SE Asia Standard Time, UTC+07:00) (ASP.Net)

aspnet_merge.exe exited with code 1 - read on...

There are a few good articles around that describe the differences between the default Web project in VS2005, and Web Application Projects (which are included with SP1 now). Having come from custom scripts using XCOPY in VS 2003 - I was comfortable with the Web Application Project model - knowing that the site would be compiled into a single DLL which along with all the required files to run the site - could just be copied/XCOPYd/FTPd into production.

I also think the loose directory structure and compilation options of the standard Web Project in VS2005 are pretty cool too. That said for a lot of Web applications - I think the Web Application Project makes a lot of sense.

Rick Strahl has written a pretty good summary of the issues and differences between the default Web Project and Web Application Project formats - at Web Application Projects and Web Deployment Projects are here

We recently switched back to a Web Application Project on one project - but wanted to keep the Web Deployment Project - since the compiler options, pre and post build command options (in the source project file) were a convenient place to perform configuration specific tasks in a build.

For one site in particular we wanted to be able to publish new binaries quickly if needed and so the Web Deployment options were set to 'Merge all outputs to a single assembly', and 'Treat as libaray component'.

I chose the default namespace for the Web Application Project as the assembly name to merge to in the Web Deployment Project.

And at that point I was stuck - the build failed with am  '"aspnet_merge.exe" exited with code 1' failure message.

I enabled Detailed MSBuild messages in the Output window - (Tools, Options, Projects and Solutions, Build and Run - bottom combo box) and saw the following message the next time I tried to build.

The target assembly 'DCL.MG.Web' lists itself as an external reference.

After some experimenting - I told the Web Deployment Project to build to an assembly with a different name - in this case "DCL.MG.Website" - and I discovered two assemblies in the output directory.  One called DCL.MG.Web.dll (from my Web Application Project) and one called DCL.MG.Website.dll which the Web Deployment Project had created.

Using IL DASM - I could see that the DCL.MG.Website assembly had only two classes in it - an ApplicationBrowserCapibilitiesFactory and global_asax. The rest of the site had compiled into the DCL.MG.Web assembly fine.

I can live with this extra assembly - it's small and uploads fine with the other binaries when we do an update. I'm just a little curious as to why this is happening - why we're not getting a single assembly, and whether anyone else has discovered this as well.



| Comments [0] | | #  
Monday, May 07, 2007
Monday, May 07, 2007 6:54:30 PM (SE Asia Standard Time, UTC+07:00) (C#)

Back in March I went to the MSDN Roadshow in London to see presentations on several topics - one of them was LINQ.

In my attempts to keep up with the avalanche of software coming out of Microsoft - I have a short list of beefy books to read, weblogs to keep up with, and videos and Webcasts to watch.

The presentation at the roadshow in March was ok - but I thought for a while about the cost of attending; the time it took to get there - the structured format of the show and my never ending need for utilitarian sources of good information.

Today I came across Mike Champion's very helpful post...

Accelerating Evolution: LINQ News from Mix 2007 which includes a link to a video of Anders' presentation at Mix 2007 .

Anders' presentation is brilliant; fluid and clear - and really demonstrates the LINQ language enhancements well.

What's more I was able to watch it at a time of my choosing, and at my own pace - which makes me wonder a little about the real benefit of the Roadshows (apart from the less than subtle injection of a lot of MS Office 2007 mini-marketing presentations between each of the main items of the event).

Mix 07 on the other hand is a 'whole-n-other' thing.... :-)



| Comments [0] | | #  
Sunday, April 29, 2007
Sunday, April 29, 2007 4:38:34 PM (SE Asia Standard Time, UTC+07:00) (Utilities)

For a while now I've been backing up my important data to a removable 80GB USB drive (two actually - one for on-site storage and one for off-site).  I've been using a utility called SmartSync Pro which I've routinely recommended to friends who want to back up their files to a removable drive.

I finally got round to creating some proper batch files today using Robocopy to perform my backups. Robocopy copy ships with Vista and it's a cool file copy utility. For maintaining an in-sync external drive it's great because by default it will only copy files that have timestamp or filesize changes - so that covers new or updated files. It also has a purge option (/PURGE) that when combined with the empty directory option (/E) will remove any orphaned files from the external drive (both of these options can be combined with the /MIR switch which mirrors the destination drive).

I also needed to stop SQL Server and related services so that database files would be backed up as well  - NET STOP <service_name> for each service is included in the batch file along with a NET START <service_name> after the backup has completed.

The last batch file I created simply clones my regular backup drive to a second removable drive for off-site storage.

Several of the comments and variable declarations in the attached batch files were created by another author (the log file format setting in particular) - a sample I found on the net, and for the life of me I can't find the link back to the original files to give credit to (apologies in advance if you happen to come across this post).

I still use the Vista System Backup - creating a Windows Complete Backup - to backup my OS as an image - but I find Robocopy much more flexible (and fast) for backing up data that will be available on removable media - especially when combined with an on and off-site media strategy.

BatchFiles.zip



| Comments [0] | | #  
Saturday, April 21, 2007
Saturday, April 21, 2007 5:03:44 PM (SE Asia Standard Time, UTC+07:00) (Enterprise)

NOTE - see Part Two of this article here...

I've recently been working on a component for a client that requires several implementations of a base class and interface including internal class dependencies.

I'd also been lurking over a couple of blog entries on the topic of Inversion of Control Containers and the Dependency Injection pattern and trying to work out the best strategy for configuring the base provider class as well as the dependencies, and so for the first time I was thinking - hmmm.. a case for DI and a pluggable architecture.

I'm by no means an 'Alpha Geek' where DI, IoC and pluggable frameworks go, however I've been using EntLib and various providers in .Net for a while now and my curiosity was peeked when Enterprise Library 3.0 shipped with its very own Application Block Software Factory.

A brilliant blog writer by the name of Jeremy D. Miller has posted a series on DI and IoC - such as The Dependency Injection Pattern – What is it and why do I care? and Thoughts on Building Pluggable Frameworks.  I'd been looking at StructureMap and Castle Windsor as possible starting points.

I've also been following the evolution of the Guidance Automation Toolkit and the Guidance Automation Extensions. There's some cool stuff going on here with the software factories released so far.

So... while StrctureMap looks like an excellent choice (although I should stress I'm really not qualified at this stage to compare the two) - I decided to try it the Microsoft way first using GAX and the Application Block Software Factory ... and here are the results - a Foo Application Block sample app (Zip)

There aren't any QuickStart sample apps for an Application Block using the software factory (at least not yet) and the docs supplied are clear but very brief and so a little digging was required. Tom Hollander has posted three video tutorials on getting started with this software factory - Enterprise Library: The Videos. The first two demonstrate the creation of providers for existing application blocks. The third one takes you through the creation of a custom application block. As an aside - the Configuration namespace in .Net 2.0 is large and daunting at first - but there's some powerful stuff in there. It helps a lot if you're familiar with the most common classes in the configuration namespace, ideally having created at least one configuration section using the ConfigurationSection base class.

I also wanted a simple App.config ready to go with my new block and configuration settings including custom settings for a provider. While Tom's video demonstrates this - the screen width was too narrow to see some of the settings he'd used including the most important reference to the section handler type.

After watching the videos and trying it out - a couple of hours later I'd got the hang of it and can now produce a custom application block, base provider and configuration classes in about five minutes; not a bad return.

The only dependencies in the new custom block are the Microsoft.Practices.EnterpriseLibrary.Common and Microsoft.Practices.ObjectBuilder namespaces - so if you're already using Entlib - these shouldn't worry you - and if you're nervous about getting into bed with GAX and GAT too soon - then with one custom application block in the bag - you can use this as a template for other projects without GAX. Creating new providers within the project is very straightforward.

One mistake I made that caused me to get hung-up for a few minutes - was a typo in the type declaration in the App.config settings file for my first concrete provider (CoolFooProvider) - if you make this mistake you'll get the following exception at runtime - "The [Assembler] attribute is not set in the configuration object type Foo.Configuration.FooProviderData." (for your base provider data class). Since this is the base type for concrete provider data class it's not decorated with the [Assembler] attribute; it's never meant to be 'assembled'. The application block couldn't find my concrete implementation (because of the config typo) and so fell back to trying to assemble the base class. Check your config file carefully if you see this message.

I also didn't like the default name of the ApplicationBlockSettings class that was created by the software factory - but this is a simple search and replace in files from VS - in this case renaming ApplicationBlockSettings to FooSettings. This is important though since this is the class that handles the section - and the one that you'll need to reference in your App.config section definition.

And very lastly - I prefer my section definition names to be camel cased (and so do the authors of the main EntLib blocks) and so a quick change to...

"public const string SectionName = "foo"" in FooSettings was in order.

My objective in the exercise was to see how quickly I could create configurable providers for the base and interface definitions for the component - including the correct settings for App.config since I did not want to depend on the designer for configuration setting creation. Like most things - it's quick and easy once you know how. Here's the link again to a working demo of a custom application block - Foo application block (Zip).

The next step in the project will be to create two new provider bases and interfaces for the nested dependencies (this is the main design goal of the block - otherwise I'd be using a simple FactoryClass to create the component). The constructor for the parent provider will simply call ProviderFactory for the nested providers based on one of the string settings in the parent provider, and of course the App.config will contain another list of possible provider entries for the child providers. If you've made it to your first custom Application Block then this next step is a breeze.

If I were more knowledgeable about StructureMap and the Castle Windows Container - I'd make some comparison comments - but I'm not (yet) so I wont. I've read enough so far to know that I'm in good shape for the first step in the process which is a good object configuration and creation strategy.

Containers are next....



| Comments [0] | | #  
Tuesday, April 03, 2007
Tuesday, April 03, 2007 3:46:04 AM (SE Asia Standard Time, UTC+07:00) (WPF)

For a while now I’ve wanted to build a small application that would take a set of images and generate a set of previews, thumbnails and metadata xml ‘sidecar’ files that I could upload to my blog (I have a gallery viewing ASP.Net control that reads the directory structure and displays the gallery - and yes I have rendered image on the fly using an HTTP handler and GDI.Net in the past – but I prefer to upload my photo albums as pre-generated packages). 

I figured this was a chance to crack the covers of my WPF book and build my first small WPF application.  I got there in the end – and I learned a LOT about WPF in the process. 

I used the WPF SDK Photo Viewer Demo as a starting point. This was just enough to get me going with a ListBox control and some special formatting using control templates, but there was still a long way to go. 

Here’s what I’ve learned from this relatively small exercise. 

  1. WPF window controls have a minimum width and minimum height property. As silly as this may sound, it took me a few minutes before I realised these existed; however they were important since I wanted my XAML layout to be liquid with a fixed right hand panel and canvas, and an expandable listbox. Setting a minimum width prevented the liquid layout from shrinking too far (like a good'ol CSS liquid design).

  2. I learned how to use the Grid, StackPanel, Canvas and DockPanel controls. You really have to crack these first before you can do anything useful in WPF – especially if you were expecting a fast start like Windows Forms will give you when it comes to dropping controls onto a form. Expression Blend helps – but I switched to XAML source to tweak the layout regularly. What’s more I could only get control events to ‘wire-up’ in my code behind files when I placed the event handler name in Expression Blend. Double clicking on the control in VS 2005 will not create the event handler in code for you. No doubt when Visual Studio Orcas is released this will change.

  3. Watch out for BitmapEffects in a list – or on any other element that occupies a large area of the window (like GroupBox controls). Here’s a couple of good links on performance in WPF: Maximizing Performance in WPF and Optimizing WPF Application Performance and specific to the BitmapEffect -Bitmap Effects Overview. Bitmap Effects render in software and the delay in maximizing the window and scrolling the ListBox was dramatic when BitmapEffects were attached to the list and other large window controls.

  4. Triggers in a ControlTemplate are awesome – but I wanted to apply a BorderBrush to a border that surrounded a ListBoxItem for the IsFocused trigger – and the Border control does not have a property trigger for IsFocused. Here’s how you do it from the ControlTemplate for the ListBoxItem:
     
    <Trigger Property="IsFocused" Value="True"> <Setter TargetName="ItemBorder" Property="Border.BorderBrush" Value="#FF8877BB"/> </Trigger>

    Once you’ve defined the triggers – you can set the property of any named control in the XAML control tree by setting the TargetName. It took me ages to work this out. I just named the Border that I’d placed around the template ‘ItemBorder’ and then set the trigger setter as followsJust to be clear, this is a trigger defined in the ControlTemplate for the ListBoxItem - but it is changing the property of another named control in the XAML mark-up; the Border control named ItemBorder. Way cool

  5. When viewing Thumbnails – don’t use the Thumbnail property of the BitmapImage or BitmapSource – it may not be oriented the same way as the full image if you have rotated the image (depending on the software you’ve used to rotate the image). Instead use the DecodePixelWidth of the BitmapImage when you open the file and give it a decent size for thumbnails. I kept the Zoom feature of the SDK sample app – but modified it to give my ListItemControl template a rectangular shape. Having larger resolution thumbnails to back up the Zoom feature meant that this was now a useful method for selecting images without necessarily having to open a larger preview window.

  6. The world of binding – I learned a lot about binding including binding property values of one control to the values of another (the Zoom effect). I also learned something very useful from this blog post on how to get the PlacementTarget for a context menu click from this entry… Binding ContextMenu to its logical Parent.

  7. Although there’s a ton of glassy button effects out there – I found this link very helpful in getting an animated glassy effect for my apps buttons – Creating a Glass Button: The Complete Tutorial. A great intro to Storyboards and Animations.

And here’s the result..(click on the image for a larger version).

My First WPF App



| Comments [0] | | #  
Sunday, March 25, 2007
Sunday, March 25, 2007 12:35:21 AM (SE Asia Standard Time, UTC+07:00) (ASP.Net)

Discovered Mike Ormond's blog after the MSDN Roadshow - which in turn led me to this definitive article on ASP.Net Viewstate from Dave Reed. Mandatory reading.



| Comments [0] | | #