DEV Community

Discussion on: Kentico Xperience Design Patterns: MVC is Dead, Long Live PTVC

Collapse
seangwright profile image
Sean G. Wright Author

There's no link to external code, but there is also nothing special with the code. If you can create a Page Template and a View Component, then you've followed the pattern.

Was there something specific you were looking for an example of?

Collapse
yuriyskentico profile image
Yuriy Sountsov

No, nothing specific, just the whole thing in general.

Collapse
dmueller78 profile image
Dave Mueller

Hi, Sean. Great article, thank you for taking the time to share it! Would you be willing to share a sample project (GitHub?) of the PTVC pattern being implemented in a generic Kentico 13 .Net Core Dancing Goat project in the interest of helping less experienced Kentico developers (like myself) to better understand the principle through a working example? I like the idea of PTVC, but just need a little more clarity on it that a sample project could provide. I've been evaluating Kentico 13 (.Net Core) for a couple months trying to pull as much from the official docs and the Dancing Goat sample project as possible. The problem I've run into now is that when I create a custom page template that needs business logic, I was guided into injecting a service class into the page template by Kentico docs. Now I'm trying to figure out how to shift to PTVC. Ultimately, I'm working toward custom business logic along with support for the page builder and have not been successful in achieving that. PTVC seems like it might be a great way to get there without resorting to custom routing and MVC controller-based logic. Thanks! -Dave

Thread Thread
seangwright profile image
Sean G. Wright Author

Dave,

Glad to hear you've been evaluating Kentico Xperience! It's a great platform!

The Dancing Goat project is really meant as a feature demo, and not necessarily an architectural/developer guidance project.

Check out this blog post to understand some of the nuance of the different project examples available out there:

devnet.kentico.com/articles/kentic...

If you are looking for a kitchen sink approach that will get you up and running fast (or you don't feel comfortable designing your own patterns and project internals), check out the Kentico Xperience 13 Baseline, maintained by my fellow MVP Trevor:

devnet.kentico.com/articles/get-st...

I don't have any good examples online at the moment of PTVC, but I could definitely provide an example (through a GitHub repo or Gist) that should point you in the right direction.

The key to PTVC is to take what you would have done in a Controller Action and move it to a View Component.

Then, in your Page Template, call that View Component to perform the business logic.

If the View Component needs context about the current Page to query for the right data from the database you can either pass that as a parameter to the View Component from the Page Template using pattern matching to get the correct type:

@* AboutUs Page Template *@
@if (Model.Page is not AboutUsPage aboutUs)
{
  return;
}

<vc:about-us-page page="aboutUs" />
Enter fullscreen mode Exit fullscreen mode

Or you can use the IPageDataContextRetriever in your View Component to get the current Page's information.

Does this help?

Thread Thread
dmueller78 profile image
Dave Mueller

That's very helpful, Sean. Thank you for the response with the links and clarifications. I'll give it a go! -Dave

Thread Thread
dmueller78 profile image
Dave Mueller

@seangwright I was able to get it working that way. The only thing I haven't been successful at is passing the page into the component as a parameter in the vc: tag... something I'm missing with the "pattern matching" I think. But I was able to use the alternative approach you suggested and get the page context from within the view component itself by way of the IPageDataContextRetriever. Thanks again for sharing your insight on the PTVC pattern and helping me along the way to implementing it. Cheers! -Dave

Thread Thread
seangwright profile image
Sean G. Wright Author • Edited on

Dave,

The key to the pattern matching is to 'exit early' if the type isn't correct. That was C# will know that in the rest of the View, the type is what you expect

@model ComponentViewModel<YourPageTemplatePropertiesType>

@if (Model.Page is not YourPageType myPage)
{
    return;
}

<!-- from here on, C# knows Model.Page is YourPageType and myPage is safely typecast as YourPageType -->
<vc:your-view-component page="myPage" props="Model.Properties" />
Enter fullscreen mode Exit fullscreen mode
public class YourModelTypeViewComponent : ViewComponent
{
     public IViewComponentResult Invoke(YourPageType page, YourPageTemplatePropertiesType props)
     {
          // ....
     }
}
Enter fullscreen mode Exit fullscreen mode