1

I'm a software engineer that primarily writes C code but now and then makes .Net applications for fun. This is a question about the fun part. Over a duration of about 15 years, I have used and expanded my own framework and now I am stuck. I would love feedback from someone who has experience in writing complex applications in a high-level language!

Okay, remember, this is about fun! I am fighting the hard fight with C and enjoy playing around in the world of C# which is why I am trying to facilitate an architecture with my framework that provides the following properties:

  • the application logic is assembled from reusable parts
  • these parts can be addressed, replaced and extended using plugins
  • design time support (i.e. the UI is fed with data in the designe time)

I am using WPF and the MVVM pattern. I created a set of "services" which provide encapsulated functionality (logging, localization, themes, settings etc.). They implement interfaces which are used by MEF (https://docs.microsoft.com/de-de/dotnet/framework/mef/) to access/instantiate their instances.

This is the list of needed assemblies for an app:

  • app design time assembly (design time implementations of app services, optional)
  • framework design time assembly (design time implementations of framework services, optional)
  • multiple possible extension assemblies (replace or add app and framework services, optional)
  • extension app assembly (UI, app service interfaces)
  • main app assembly (UI, app services)
  • framework assembly (framework services and their interfaces)

I am using a filtered MEF container to load exports from the assemblies in the listed order, while dropping subsequent exports of the same export type identity. Design time assemblies are only used when running in the VS/Blend Designer.

Most of what I want is already there. I can reference the extension app assembly and the framework assembly to write extension assemblies for the app. These extensions can interact with all used services, replace them and introduce new ones. There is also a service that manages the panes of the docking UI, so extensions can introduce new visuals.

The ViewModels are manually assigned to the views and use Constructor Injection to get hold of all needed services.

Most services manage a list of models that provide further functionality. These models are accessed primarily by the UI (via ViewModel>Service>Model) and contain a large part of the actual logic.

Now to the problem: I have to move all my models into the extension app assembly as they are referenced by the service interfaces. This seems wrong. Also, I loose access to some important properties from the main app assembly. I feel like I made a wrong turn somewhere.

A) I could embrace the anemic domain model and reduce my models to mere data containers. That would move the logic back to the services, but I think this is a horrible idea (in addition to the obvious reasons, it feels like WPF was totally made for domain-driven design).

B) I could make interfaces or abstract classes for all models. That is a lot of work! It would also make writing services less fun (type covariance issues).

I am doing this for fun and would accept drastical changes, if the result is better :)

How should I handle the models in my setup? Thanks in advance, I know this is quite a text!

enter image description here

11
  • Do you have a diagram we could look at? Mar 4, 2021 at 18:24
  • Good idea, I'll make one... Mar 4, 2021 at 18:25
  • While you're doing that, a few initial thoughts: Mar 4, 2021 at 18:31
  • 1. I hear what you're saying about Anemic Data Models, but you shouldn't be afraid of them; they are literally everywhere. JSON services embrace them, ORM's embrace them. Even data binding in WPF itself is essentially a "data-only" computing model. C has lived without full object-orientation support for decades now, with few ill effects. Mar 4, 2021 at 18:32
  • 2. As far as making interfaces for everything, I would constrain that to those things that need to be unit tested. Unit testing is going to demand interfaces anyway. Model classes and ViewModel classes in WPF shouldn't need interfaces unless you intend to use them in a "common" way, like IEnumerable or IComparable. Mar 4, 2021 at 18:34

1 Answer 1

0

Based on the responses of @Robert Harvey, some more research and actually trying out the mentioned scenarios I feel like making interfaces for all models used by the services is the best choice. This way, the models are an implementation detail of the services - which are just singleton domain models that are injected to allow extensibility etc. This approach also allows fine grained unit testing.

1
  • To clarify, use an interface when you want two or more implementations. A unit test counts as an implementation. I say this because I have written many UI's successfully that don't contain any unit tests at all, and therefore don't need any interfaces because there is a single implementation of each class. Aug 12, 2021 at 12:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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