views:

211

answers:

5

I am using Silverlight with a DDD approach. I have a Person domain object that has properties such as FirstName, LastName, Address, etc. The Person needs to have an Image.

What is the best way to handle this?

I don't really want to put an Windows.Controls.Image property on the Person object because this it will be coupled to Silverlight/WPF and I might want to use this object with some other technology in the future (ASP, WinForms, the next new thing, etc).

I also need to be able to save and load the image somewhere. Is it best practice to save the image to a database or to a file system? I am currently using nHibernate with Microsoft SQL Server, but I also want to be able to support nHibernate with mySql and possibly some other databases. It is also possible that I may some day want to replace nHibernate with entity framework or some other technology (I am abstracting this out using a repository).

Given this information, how should I handle Images for my Person?

+4  A: 

Well, byte[] (or something wrapping a byte[]) is fairly portable... most anything else is going to be implementation specific.

Re database vs file... for the purposes of the client apps (Silverlight, WPF, etc) I would probably expose them via a web page rather than a WCF (etc) call - i.e. some ASP.NET handler (or ASP.NET MVC route) that returns the image via an http call. Then all you actually need in the client is the path to the image (/people/images/12345 or whatever).

For storage - either is usually fine... in SQL Server 2008 you can do both at once with the file-stream type. One of the problems with storing BLOBs in the database is increasing the size, but a few (small) images won't usually hurt (unless you are using SQL Express and have a capped db size). But using the database has the advantage that a single backup includes everything.

Saying that, though: almost every implementation I've done like this has used files.

Marc Gravell
@marc, typo in there I presume "SDL2008" should be "SQL2008"
Nathan Koop
Indeed. Will fix.
Marc Gravell
+1  A: 

Best practise is to encapsulate difficult decisions. Define your own Image class and hide the implementation.

Assuming you're not writing an image editing application, the domain part of your Image class is going to be thin. Presentation and storage are not in your domain image class, they are in adapters.

Stephan Eggermont
A: 

Hm, there is System.Drawing.Image which is pretty much technology-independent. It represents exactly what you want (imo): Something that can be loaded/saved from/to some stream in some well-known image format and that can be displayed on the screen (either in WinForms or WPF).

MartinStettner
Too lazy to check, but I'm pretty sure that System.Drawing.Image - being GDI+ - is IDisposable. I'd hate to have to implement IDisposable in a domain object.
Mark Brackett
System.Drawing.Image is a big no-no from a DDD perspective. You just killed any possibility of technology switch
Stephan Eggermont
+2  A: 

Are you actually using the binary blob for anything? If not, pass around a reference to something on the filesystem. I'd be worried about pissing things off if you start carrying around byte[]'s or something.

If you are WPF, everything takes a URI as an ImageSource:

BitmapImage pic = new BitmapImage(new Uri("YourAssembly;components/images/something.jpg"));

Keep in mind that if you go my suggested route and move this to Silverlight, you'll need a crossdomain.xml file on the domain you are dishing these things out.

If you do need to mess with the binary blob, then keep all that as a Stream of some form and have your Person.Image class offer a way to get a StreamReader/StreamWriter like GetImageStream(). Then your database stuff can get a StreamReader and go write that stuff into the database. Without checking, my guess is just about every database out there that has binary blobs writes out using a Stream, not byte[].

...Just some thoughts. Dont forget BitmapImage lets you tap into its Stream too, but you'll have to look that up in the docs :-) Hope that helps.

Cory R. King
+1  A: 

I'd go with the file system for several reasons:

  1. You don't have to store the image type in a separate field (BMP? JPEG? PNG?)
  2. You have the option of using a lightweight, finely-tuned server to serve your images (or, several, if your scaling needs demand it)
  3. You don't need to mess with byte[]s in your code - just use a string
  4. You'll have fewer problems if you decide to change database - you might even be able to get by with INSERT scripts for your migrations
elo80ka