Lead Product Evangelist @Kentico, Founding partner @craftbrewingbiz. love to learn / teach web dev & software engineering, collecting vinyl records, mowing my lawn, craft 🍺
Thanks for reading and I'm glad the posts have been helpful.
Hmm... that seems like a lot. Does your page type actually have 20-30 fields? This might be a content modeling issue that is leading to a technical one.
Have you looked at AutoMapper? It can help with passing data between layers, especially when the types and property names are pretty well aligned. This allows each layer to own its own types which is important when keeping them loosely coupled.
Another option is to break up the data into groups that get mapped to the view through child actions. Assuming your data access is cached, calling the same DB query APIs multiple times won't cause issues, and you can then map your page type into different DTOs that returned by separate child action calls in the same view.
You can try this same approach with MVC widgets if you also need a flexible layout (have different widgets display different sets of values from the current page).
Finally, all rules and patterns are meant to be broken when appropriate.
If you don't have complex business rules and instead are mapping page type fields directly to the view, then it might make sense to even put the DB access in the controller and have the page type be the view model.
This last approach trades loose coupling and the ability to decorate and apply cross cutting for the benefit of simplicity.
Kentico Experience 13 is going to have Route To View where you are provided a strongly typed view model that is your page type instance... no customer controllers or repositories are needed.
There are pros and cons to each approach. Some require more up front work but allow more flexibility while others are far faster (and maybe less complex).
The key is to make informed trade offs where you (and your fellow devs) understand and agree on the costs and benefits.
Content sites might not need an Onion architecture, just like CRUD apps might not need Event Sourcing and Kuberentes... 😁
Lead Product Evangelist @Kentico, Founding partner @craftbrewingbiz. love to learn / teach web dev & software engineering, collecting vinyl records, mowing my lawn, craft 🍺
I just realized I might have skipped answering your specific question 🤦♂️!
If you are using an Onion architecture, then you should have a domain class (HomePageData) that is in your Core project. By having it there you can't take a dependency on your data access implementation project (let's call it Data).
This means HomePageData will need to have a constructor that only accepts:
Primitive .NET type parameters
Other types in your Core project
So you can't use the generated HomePage page type class as a parameter.
Each layer should own its abstractions, which means the HomePageData and (if you are using a repository pattern) the IHomePageRepository should be defined in Core, while the Data project will have an implementation of IHomePageRepository which will return HomePageData.
Core
HomePageData (domain class)
IHomePageRepository (domain abstraction)
Data
HomePage (custom page type class)
KenticoHomePageRepository (implementation of domain abstraction)
Now your presentation project (let's call it Web) will rely on the abstraction and domain type and never access the types in Data directly:
Notice here that it's ok for the HomePageViewModel to depend on the domain abstraction HomePageData - domain types are meant to be used everywhere since they don't have any volatile dependencies themselves, instead it's the implementations that we want to keep isolated.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Hey Andy!
Thanks for reading and I'm glad the posts have been helpful.
Hmm... that seems like a lot. Does your page type actually have 20-30 fields? This might be a content modeling issue that is leading to a technical one.
Have you looked at AutoMapper? It can help with passing data between layers, especially when the types and property names are pretty well aligned. This allows each layer to own its own types which is important when keeping them loosely coupled.
Another option is to break up the data into groups that get mapped to the view through child actions. Assuming your data access is cached, calling the same DB query APIs multiple times won't cause issues, and you can then map your page type into different DTOs that returned by separate child action calls in the same view.
You can try this same approach with MVC widgets if you also need a flexible layout (have different widgets display different sets of values from the current page).
Finally, all rules and patterns are meant to be broken when appropriate.
If you don't have complex business rules and instead are mapping page type fields directly to the view, then it might make sense to even put the DB access in the controller and have the page type be the view model.
This last approach trades loose coupling and the ability to decorate and apply cross cutting for the benefit of simplicity.
Kentico Experience 13 is going to have Route To View where you are provided a strongly typed view model that is your page type instance... no customer controllers or repositories are needed.
There are pros and cons to each approach. Some require more up front work but allow more flexibility while others are far faster (and maybe less complex).
The key is to make informed trade offs where you (and your fellow devs) understand and agree on the costs and benefits.
Content sites might not need an Onion architecture, just like CRUD apps might not need Event Sourcing and Kuberentes... 😁
I just realized I might have skipped answering your specific question 🤦♂️!
If you are using an Onion architecture, then you should have a domain class (
HomePageData
) that is in yourCore
project. By having it there you can't take a dependency on your data access implementation project (let's call itData
).This means
HomePageData
will need to have a constructor that only accepts:Core
projectSo you can't use the generated
HomePage
page type class as a parameter.Each layer should own its abstractions, which means the
HomePageData
and (if you are using a repository pattern) theIHomePageRepository
should be defined inCore
, while theData
project will have an implementation ofIHomePageRepository
which will returnHomePageData
.Core
HomePageData
(domain class)IHomePageRepository
(domain abstraction)Data
HomePage
(custom page type class)KenticoHomePageRepository
(implementation of domain abstraction)Now your presentation project (let's call it
Web
) will rely on the abstraction and domain type and never access the types inData
directly:Notice here that it's ok for the
HomePageViewModel
to depend on the domain abstractionHomePageData
- domain types are meant to be used everywhere since they don't have any volatile dependencies themselves, instead it's the implementations that we want to keep isolated.