The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

falthazar (7) [Avatar] Offline
#1
So I want to start building a WPF application to display data from a database. Essentially attempting to migrate an Access database to SQL and WPF.
I've decided to use EF Core for the database, and Caliburn Micro with SimpleInjector for the WPF app.

I'm still sort of new to programming, and want to make sure I start the design on the right foot. However, I'm a little confused about what goes in each layer, and the best way to design this in a way that I could replace the WPF app with a web app in the future.

I haven't finished the book, so I apologize if any of these are addressed later (I'm on ch 7, let me know if I should just wait till I finish..).

For the UI layer, should that have only the views, or the ViewModels as well?
It seems like most WPF applications suggest you inject the VMs into the view, but I'm not exactly sure why? In ch 7.2.2, you say "MVVM ViewModels, on the other hand, are components with Dependencies." I sort of understand that, but I don't quite get why the views and VMs can't be tightly coupled, and have the VMs created with injected dependencies. What is a scenario where you'd want to inject a different VM?

In the DI first edition, it looks like the VMs and views are in separate projects and use a factory and adapter - is that still suggested? The SimpleInjector documentation suggests no?

Sort of related, while I'm not familiar with web apps at all yet, isn't doing
IEnumerable<DiscountedProduct> featuredProducts = ...
in HomeController tightly coupling the UI and DAL?

I realize it is a bit late now since the book is nearly finished, but what was the reasoning in removing the WPF chapters in the second edition? WPF still seems to be the best option for .Net desktop apps, especially for enterprise apps. UWP adoption seems to be pretty slow due to needing Win 10, and a lot of companies not willing to migrate. I feel like WPF chapters are still very relevant, even more so than UWP.


For the data access and domain layers, I think I understand where things should go, let me know if I have this right:
Domain layer should have the POCOs, how data is related, any calculations, and the appropriate seams/interfaces to describe how to access the data (but not actually access it). It should also have interfaces to describe the data repository and the CRUD operations. All the other layers directly reference this, because it is the core of the application - switching this out would mean a whole new application.

Data Access layer should have the EF context, and implementations of the domain's seams like CRUD operations. We would want to do this so that we could later switch how data is accessed - for instance from Access to SQL to Azure.

Lastly, I'm still a bit fuzzy on some of the definitions like what exactly is considered business logic, what service means vs a controller. Is there a good resource that would list those common definitions? Or should I just wait till the glossary is done?
Steven van Deursen (43) [Avatar] Offline
#2

> but I don't quite get why the views and VMs can't be tightly coupled, and have the VMs created with injected dependencies.


A ViewModel in MVVM is always tightly coupled with its view, j

In chapter 7, ViewModels are actually injected into the view. You can see this in the book's code downloads, but Listing 7.6 (latest MEAP version) shows this as well. The CreatePage method of the App.xaml.cs. Here you see that the ViewModel is injected into the View's DataContext property. So Property Injection is used and the ViewModel is a dependency of the View.

Furthermore, as the XAML of the MainPage of Listing 7.5 shows, Views are tightly coupled with the ViewModel. They are perhaps not *strongly* coupled, since there is no compile-time support, but they certainly are *tightly* coupled, since the XAML uses properties of that specific ViewModel.

> What is a scenario where you'd want to inject a different VM?


You don't. You never want to do that.

> In the DI first edition, it looks like the VMs and views are in separate projects and use a factory and adapter - is that still suggested?


No, the use of factories presents an extra level of indirection that is typically not required. I would advise following the 2nd edition's UWP guidance while building WPF applications. There are some differences between the two, but from a DI perspective, this wouldn't be that much.

> I'm a little confused about what goes in each layer, and the best way to design this in a way that I could replace the WPF app with a web app in the future

> For the UI layer, should that have only the views, or the ViewModels as well?


That's actually a pretty hard to answer question. In the first edition, UI and presentation layer are separated, which might be a good thing to do when your application gets bigger. On the other hand both the UI and PL will be specific to WPF. You can throw them away completely when moving to a web application.

Important, however, is to keep your domain and DAL separated. In that respect, chapter 10 will probably be of a lot of help in designing that part of the application.

> isn't doing `IEnumerable<DiscountedProduct> featuredProducts = ...` in HomeController tightly coupling the UI and DAL?


No. DiscountedProduct is defined in the domain layer, so this tightly couples the UI with the domain layer, but that would unlikely be a problem, since the domain is the core part of your application. For a more elaborate discussion, see the "Dependency Inversion Principle" section of section 3.1.2.

> what was the reasoning in removing the WPF chapters in the second edition?


Reasoning was that in this edition we are targetting .NET Core related technologies specifically, and WPF was already discussed in the first edition, which comes as free PDF with your purchase. Most of the advice given in 7.2, however, is applicable to WPF as well.

> or the data access and domain layers, I think I understand where things should go, let me know if I have this right:


Your description seems pretty accurate, which implies that we did a good job in describing it smilie

> what exactly is considered business logic


This actually is a bit fuzzy, and during the lifetime of your project, you will from time to time get into discussions over where a piece of logic should reside. In chapter 2, we state the following (last paragraph of 2.1.2):

Domain logic is all the behavior that the application needs to have, specific to the domain the application is built for.


So when that behavior is specific to the domain, the domain layer is where to put it.

If you want to learn more about building complex domains, Eric Evans' book "Domain-Driven Design: Tackling Complexity in the Heart of Software" (Addison-Wesley, 2004) is a great place to start.

> what service means vs a controller.


"Service" is an awfully broad term. In chapter 1 we state:

In DI terminology, we often talk about services and components. A service is typically an Abstraction, a definition for something that provides a service. An implementation of such Abstraction is often called a component, a class that contains behavior.


In the context of the ProductService of chapter 2 and 3, however, the service postfix is used to state that it is part of the domain layer. This is a very common practice, and in this case the name does not imply an abstraction, but just something that provides a service. As you'll learn in chapter 10, however, such design for services often isn't the most ideal.

Controller as well can mean several things. In the book the term controller typically refers to the controller of the Model-View-Controller (MVC) pattern. In that case, "MVC controllers are responsible for responding to requests made against an ASP.NET MVC website. Each browser request is mapped to a particular controller." (source: https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/aspnet-mvc-controllers-overview-cs)

> Is there a good resource that would list those common definitions?


Many of those pattern names come from Martin Fowler's book "Patterns of Enterprise Application Architecture" (Addison-Wesley, 2003)

> Or should I just wait till the glossary is done?


The glossary will not contain descriptions for terms like service, controller, repository, decorator, and other patterns. The glossary will only contain the book's terminology words (in the MEAP printed as bold), which include patterns like Composition Root, Constructor Injection, and Singleton Lifestyle, anti-patterns like Service Locator and Ambient Context, and common design principles such as the SOLID principles and CQS.

I hope this helps
falthazar (7) [Avatar] Offline
#3
but I don't quite get why the views and VMs can't be tightly coupled, and have the VMs created with injected dependencies.

A ViewModel in MVVM is always tightly coupled with its view, j

In chapter 7, ViewModels are actually injected into the view. You can see this in the book's code downloads, but Listing 7.6 (latest MEAP version) shows this as well. The CreatePage method of the App.xaml.cs. Here you see that the ViewModel is injected into the View's DataContext property. So Property Injection is used and the ViewModel is a dependency of the View.

Furthermore, as the XAML of the MainPage of Listing 7.5 shows, Views are tightly coupled with the ViewModel. They are perhaps not *strongly* coupled, since there is no compile-time support, but they certainly are *tightly* coupled, since the XAML uses properties of that specific ViewModel.

I guess my question is why are they injected at all? How is using DI in this case different than just setting the data context property in main view method?


In the DI first edition, it looks like the VMs and views are in separate projects and use a factory and adapter - is that still suggested?

No, the use of factories presents an extra level of indirection that is typically not required. I would advise following the 2nd edition's UWP guidance while building WPF applications. There are some differences between the two, but from a DI perspective, this wouldn't be that much.


Sorry, I didn't think to check first how similar the two are! I was an idiot and I sort of just wrote off UWP before I took a real look.

I'm a little confused about what goes in each layer, and the best way to design this in a way that I could replace the WPF app with a web app in the future

For the UI layer, should that have only the views, or the ViewModels as well?


That's actually a pretty hard to answer question. In the first edition, UI and presentation layer are separated, which might be a good thing to do when your application gets bigger. On the other hand both the UI and PL will be specific to WPF. You can throw them away completely when moving to a web application.

I'm assuming this is more of a personal choice, but for a single developer there isn't really a difference between keeping the PL in a folder under the UI project vs having a separate project? It more or less comes down to how you like to keep your code organized?


isn't doing `IEnumerable<DiscountedProduct> featuredProducts = ...` in HomeController tightly coupling the UI and DAL?

No. DiscountedProduct is defined in the domain layer, so this tightly couples the UI with the domain layer, but that would unlikely be a problem, since the domain is the core part of your application. For a more elaborate discussion, see the "Dependency Inversion Principle" section of section 3.1.2.

Yea, I got a little mixed up going back and forth between my notes and the question. I thought it was in the DAL for some reason.

what was the reasoning in removing the WPF chapters in the second edition?

Reasoning was that in this edition we are targetting .NET Core related technologies specifically, and WPF was already discussed in the first edition, which comes as free PDF with your purchase. Most of the advice given in 7.2, however, is applicable to WPF as well.

Yea that is fair. WPF will be supported in Core but not until later so it makes sense to leave it out. And again, sorry didn't realize how similar UWP is.

Your description seems pretty accurate, which implies that we did a good job in describing it smilie

Very very good job smilie. This book is fantastic, I'm reading it cover to cover.
It's funny, I had already decided on using SimpleInjector for the project because I liked the documentation so much. I was going to try and learn DI using just that, until I found this book. I didn't realize until it was mentioned in the book that you made SI! It all made sense after...


> what exactly is considered business logic

This actually is a bit fuzzy, and during the lifetime of your project, you will from time to time get into discussions over where a piece of logic should reside. In chapter 2, we state the following (last paragraph of 2.1.2):

Domain logic is all the behavior that the application needs to have, specific to the domain the application is built for.

So when that behavior is specific to the domain, the domain layer is where to put it.

If you want to learn more about building complex domains, Eric Evans' book "Domain-Driven Design: Tackling Complexity in the Heart of Software" (Addison-Wesley, 2004) is a great place to start.

> what service means vs a controller.

"Service" is an awfully broad term. In chapter 1 we state:

In DI terminology, we often talk about services and components. A service is typically an Abstraction, a definition for something that provides a service. An implementation of such Abstraction is often called a component, a class that contains behavior.


In the context of the ProductService of chapter 2 and 3, however, the service postfix is used to state that it is part of the domain layer. This is a very common practice, and in this case the name does not imply an abstraction, but just something that provides a service. As you'll learn in chapter 10, however, such design for services often isn't the most ideal.

Controller as well can mean several things. In the book the term controller typically refers to the controller of the Model-View-Controller (MVC) pattern. In that case, "MVC controllers are responsible for responding to requests made against an ASP.NET MVC website. Each browser request is mapped to a particular controller." (source: https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/aspnet-mvc-controllers-overview-cs)

This is super helpful, thanks!
A lot of my confusion I think was from another example I was looking at, by the creator of WAF. Specifically the BookLibrary example

It has a lot of services and controllers.
I really liked it at first since it was an example of a real application that had all the elements I was looking for. But the more I learn about DI, especially the patterns and code smells in the book, I realize it might not actually be a good example. Let me know if I'm correct:
First, it uses MEF which is not DI (thanks for the explanation in edition 1- I was confused trying to figure out this app, mostly due to MEF).
The DAL and presentation logic is all in the same project, and the domain has no logic except for the EF POCOs and the actual SQLite database (which should be in a separate DAL).
There wouldn't be an easy way to switch out SQLite and SQL server without a lot of refactoring.
I think it also incorrectly uses interfaces? They are all using local defaults, and not really referenced outside their projects. All of the constructor injection seems to actually rely on specific implementations of the interfaces.
It also has a bad smell of constructor over injection - each controller has 5 or 6.
I think the controllers are an example of the controlfreak through abstract factories anti-pattern.

If I wanted to refactor I would:
Drop MEF and never look at it again (I actually like annotations most of the time, but for DI it seems overly complicated and essentially prevents wiring up the application in one place)
Split out the DAL and UI layers and ensure they are not tightly coupled.
View services should move to the UI layer
Entity services should move to the DAL, along with the email service, but their interfaces should move to the DL.
Refactor interfaces in DL to be UI agnostic (remove "OvervableCollection")
Consolidate the controllers and move them as appropriate.


> Is there a good resource that would list those common definitions?


Many of those pattern names come from Martin Fowler's book "Patterns of Enterprise Application Architecture" (Addison-Wesley, 2003)

This book and "Code Complete" are in my list of books I need to read. I tried code complete a little while ago, but I think a lot of the concepts were over my head at the time so I didn't get very far. I plan on going back to it soon since I've learned a lot since.
Steven van Deursen (43) [Avatar] Offline
#4
> I guess my question is why are they injected at all? How is using DI in this case different than just setting the data context property in main view method?


There is no difference in this case. Setting DataContext property with the ViewModel is a form of DI, it's Property Injection. Setting the DataContext with the ViewModel is, as far as I know, common practice in WPF and UWP.

> It more or less comes down to how you like to keep your code organized?


Splitting UI and PL allows them to live in different assemblies, and can prevent the PL assembly from taking a dependency on assemblies that are only of interest to the UI or Composition Root. In the first edition, the separation between UI and PL was, I believe, introduced in chapter 2. In the second edition, however, we decided to remove the introduction of the PL and with it the separation of those two layers. We felt it wasn't required to effectively tell our story.

Whether it is useful to make this split, however, depends on how important it is to prevent the assembly that contains the PL code (such as controllers or ViewModels) to have dependencies on the rest of the application.

> think it also incorrectly uses interfaces? They are all using local defaults, and not really referenced outside their projects.


Can you give an example? I did a quick browse through the project, but not sure what you are pointing at.

> I think the controllers are an example of the controlfreak through abstract factories anti-pattern.


Abstract Factories are not an anti-pattern. Chapter 6, however, does describe that some particular uses of Abstract Factories are code smells. Where do you see the Control Freak?