Friday, September 4, 2009

Duplicate Image Resources in WPF

I'm currently in the final stages of a large project. We're talking hundreds upon hundreds of man-hours, thousands upon thousands of lines of code, and even a good hundred or so image resources.

All of this, spread over 15 projects. These projects did everything from standard data access (to the local data store) to administration data access (via the central data repository) to installation and installation custom actions, in addition to the core and supporting functionality of the application itself.

It was a standard system, I had the controlling application, and a bunch of supporting, functionally-grouped class libraries.

The thing is that I built this thing working in those functional groups, and it was rare for a library to talk to another library directly. Sure, I had a library with shared functional classes and then the data layer, but in general, those units worked by themselves, and I built them separately from one another.

Which means that I had a lot of images duplicated across the project.

In fact, the Installer (a MSI file) was 15,283KB.

Which isn't that big considering how large this application is, but it's still a big file considering our distribution method is the internet.

So, I started looking at all those images, and realized something.

I didn't need them all.

Because I had a library that was built before all the other libraries, and more importantly was built as an attached library to them all, I could move all those images to that library, meaning it would only be a single place for me to call them from.

By the time I had finished moving most of the images into a single DLL (there were some images in the Reporting section that I had to leave in that library) I had the MSI's size down to 11,786KB.

And the coding involved is simple. There are in fact two ways to approach this.

The first is to modify the Image's SOURCE attribute. The usual way to do this is to use this

Source="/MyDLL;component/Folder/Image.png"
and then modify it to
Source="/MyOtherDll;component/Folder/Image.png"
Not that hard.

The second way is a bit more involved working, but is probably a better solution in the long run, especially where ease of re-usability and standardization is concerned. And that's to define it into a style for your image.

In this, you'd create a new style for an image, providing it little details such as the Source URI and then use that as a DynamicResource in your various DLLS. That would look like this:
< style="{DynamicResource UndoImage}">
But the fundamental thing to remember is that you don't need those images duplicated in every DLL that you're building for your project.

No comments:

Blog Widget by LinkWithin