1

We are working on a .NET desktop application written in C# and WPF, that communicates with a REST API server. The software has a layered design and consists of multiple projects.

  • One project for the presentation and ViewModels (we follow the MVVM pattern).
  • One project for the domain layer. The business logic like services and model classes.
  • One project for the implementation of the data layer. (In this case mainly the communication with the REST API). In the future there could be more projects for the data layer, that all have different implementations of data-ralated interfaces that are defined in the 'domain' project.

Our REST API provides an endpoint for loading images, and we want to create a service in the domain layer that makes it possible to load those images. This would mean the service class could look something like:

public class ImageService 
{
    public BitmapImage GetImage(int imageId)
    {
        // ...
    }
}

But the above class has a dependency to BitmapImage, or in other words: PresentationCore.dll. This seems to be no good for a service class in a domain layer. At the same time, it would be very useful to have this kind of service. On one hand, BitmapImage lets me think of a typical UI related object, but on the other hand BitmapImage seems to be suitable because you could consider it as a standalone class representing an image, and it is usable without any UI context (I mean, it's not a UI control/layout, doesn't depend on other UI related classes, etc.)

The problem is: is it acceptable to have a dependency to PresentationCore.dll in a project that's a pure logical domain layer. Also, a reference PresentationCore.dll implies that the project could contain more usages of classes in that DLL, and possibly makes it unclear why that DLL is referenced at all. Maybe even the mistake/temptation exists someone's going to use UI related objects from this DLL?

What would be a solution for loading images in this case?

2
  • (1) Do you need to use the functionality provided by BitmapImage as part of your business logic? (2) Do you need all of that functionality or only a specific subset? (3) Are you certain that BitmapImage is the right class, or are you just experimenting, and might at some point decide to try, say, System.Drawing.Bitmap? (4) Are you expecting to run your domain logic DLL on a platform that doesn't have the BitmapImage class and/or PresentationCore.dll? Nov 30 '21 at 6:51
  • BTW, answers so far assume that you have control over the REST service and offer suggestions under that assumption - but it's unclear from your question that you do? Is it a 3rd-party service? As I understood your question, you are asking about client-side logic? If you do have control over the web service, does that change anything - can the logic of interest be feasibly moved to the service, or does it have to be on the client? (Please edit the question itself, rather than responding in comments, so that future answeres can more easily see the clarification.) Nov 30 '21 at 7:12
4

Split the "data" and the "view": the REST side will get a binary blob which is the image in some format. Store this in an object. This goes in the data layer.

The presentation layer then needs a converter for those objects, and possibly a cache of converted images, but does no REST work.

2
  • 1
    I think the core idea in this answer is ok, but it could be improved by giving some pointers how to accomplish this in WPF (for example, this SO Q&A).
    – Doc Brown
    Nov 29 '21 at 17:03
  • If I understood the OP well, they are not using BitmapImage on the REST service side (which may even be 3rd-party), but within the domain logic layer within the desktop application, and are asking about that. Perhaps the OP could clarify. Nov 30 '21 at 7:03
2

Depending on what you're doing with the image data, there might not be a need to create a BitmapImage object in your image service.

If you're just going to display it in an Image control, then your image service can just return a byte array which you can bind directly to the image control's Source property, and the control will automatically generate the displayed image from that.

So your ImageService could be coded as

public byte[] GetImage(int imageId) { ... }

or even

public Task<byte[]> GetImageAsync(int imageId) { ... }

if the image data is being fetched from a slow source such as local file read, database or web service.

The latter form could be combined with an asynchronous property, to allow the image data to be fetched, when required, without blocking the UI thread. For an example of this, check out my blog post.

1
  • 1
    If I understood the question well, the question is entirely about the client-side desktop application; when the asker says "service", they don't mean a remote web service, but a class within the desktop app. I'm not sure if they even have control over the remote REST service implementation - I'm going to ask them to clarify. Nov 30 '21 at 7:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.