5. The basic concept of (Sitecore) MVC
5
View
Model
Controller
User
Uses
Manipulates
Updates
Sees
6. The basic concept of (Sitecore) MVC
• Views display a certain set of data. They do
not know where the data comes from.
• Models are classes that hold data.
They may also execute logic for managing this
data. They do not know how the data is
displayed.
• Controllers are classes that execute logic that
controls what data is seen and which view is
used to display it.
6
7. The basic concept of (Sitecore) MVC
A traditional ASP.NET MVC request
7
Browser URL Routing Controller Model View
Request
Invoke action
Initialize
Lookup view
Render
HTML
8. The basic concept of (Sitecore) MVC
A Sitecore MVC request
8
Request
httpBeginRequest
pipeline
MVC
route?
Layout
specified?
Is it an
MVC view
file?
Controller
specified?
MVC
request
WebForms
request
No No No
No
Yes Yes Yes
Yes
Source: Martina Welander
9. Sitecore Renderings
•View Rendering
Renders a View using a built-in controller
action. The controller passes a model of type
RenderingModel to the View.
•Controller Rendering
Calls an action on a controller and lets the
controller handle the View rendering.
9
12. Controllers
12
public class MvcDemoController : Controller
{
public ViewResult NewsOverview()
{
// Get news root item from Sitecore.
Item newsRoot = Sitecore.Context.Database.GetItem("{NEWS-ROOT-GUID}");
IEnumerable<Item> newsItems = newsRoot.Children;
// Get temperature from weather service.
var weatherService = new WeatherService();
int temperature = weatherService.GetTemperature();
// Initialize model for News Overview page.
return this.View(new NewsOverviewModel
{
NewsItems = newsItems,
Temperature = temperature
});
}
}
13. Controllers
13
public class MvcDemoController : Controller
{
public ViewResult SearchNews(string keyword, int page)
{
// Perform search and return NewsOverViewModel with results.
var model = new NewsOverviewModel();
return this.View(model);
}
}
/MvcDemo/SearchNews?keyword=my_search_terms&page=1
15. Controllers
15
Do
• Retrieve data required to
initialize models
• Initialize models
• Return appropriate View
(or other ActionResult)
Don’t
• Cramp them with logic
• Use them if it’s not
necessary
18. Models
18
public class ContentPageModel
{
public string Title { get; set; }
public string Intro { get; set; }
public string Body { get; set; }
}
public class ContentPageModel
{
public string Title { get; set; }
public string Intro { get; set; }
public string Body { get; set; }
public ContentPageModel Parent { get; set; }
public IEnumerable<ContentPageModel> SubPages { get; set; }
}
19. Models
19
public class ContentPageModel
{
public string Title { get; set; }
public string Intro { get; set; }
public string Body { get; set; }
}
public class ContentPageModel
{
public string Title { get; set; }
public string Intro { get; set; }
public string Body { get; set; }
public ContentPageModel Parent { get; set; }
public IEnumerable<ContentPageModel> SubPages { get; set; }
}
public class ContentPageModel
{
/* Snipped properties */
public void CreateSubPage(ContentPageModel model)
{
// Logic for creating a sub page.
}
public void DeleteSubPage(ContentPageModel model)
{
// Logic for deleting a sub page.
}
}
20. Model Binding
20
public class SearchRequestModel
{
public string Keyword { get; set; }
public int Page { get; set; }
public bool OrderByRelevance { get; set; }
}
public class MvcDemoController : Controller
{
public ViewResult SearchNews(SearchRequestModel request)
{
// Perform search and return NewsOverViewModel with results.
var model = new NewsOverviewModel();
return this.View(model);
}
}
/MvcDemo/SearchNews?keyword=my_search_terms&page=1
21. Models
In Sitecore MVC:
• View Models usually represent Templates from Sitecore.
• This way, View Models can contain content from
Sitecore items.
• There are several Object-Relational Mappers that are
created specifically for that task.
Make sure to attend Mike Edwards’ and Robin
Hermanussen’s session for more on ORM!
21
22. Models
22
Do
• Hold data
• Provide logic to
manipulate data
Don’t
• Add presentation
elements to data
• Use for application
logic
28. Views
28
using System.Web;
using Sitecore.Mvc.Helpers;
/// <summary>
/// Extension methods for the SitecoreHelper class.
/// </summary>
public static class SitecoreHelperExtensions
{
public static HtmlString WhoAreYou(this SitecoreHelper helper)
{
return new HtmlString("I'm your father!");
}
}
@Html.Sitecore().WhoAreYou()
@*
Output: "I'm your father"
*@
29. Views
29
public class ContentController : Controller
{
public ViewResult ContentPage()
{
var model = new ContentPageModel();
// Populate model properties with data from Sitecore.
return this.View("~/Views/Content page.cshtml", model);
}
}
public class ContentPageModel
{
public string Title { get; set; }
public string Intro { get; set; }
public string Body { get; set; }
}
30. Views
30
public class ContentController : Controller
{
public ViewResult ContentPage()
{
var model = new ContentPageModel();
// Populate model properties with data from Sitecore.
return this.View("~/Views/Content page.cshtml", model);
}
}
public class ContentPageModel
{
public string Title { get; set; }
public string Intro { get; set; }
public string Body { get; set; }
}
@model ContentPageModel
<section id="main_content">
<h3>
@Model.Title
</h3>
<p>
<strong>
@Model.Intro
</strong>
</p>
@Model.Body
</section>
31. Views
31
Do
• Display data from a
model
• Use simple flow logic
that is required to
present data
(if / foreach / retrieval
methods)
Don’t
• Add complex logic
• Go nuts with inline
code
32. Inversion of Control (IoC)
32
“A software architecture with this design inverts control as
compared to traditional procedural programming: in
traditional programming, the custom code that expresses the
purpose of the program calls into reusable libraries to take
care of generic tasks, but with inversion of control, it is the
reusable code that calls into the custom, or problem-specific,
code.”, Wikipedia
The decoupling of dependencies by isolating code for certain
responsibilities into separate libraries and referring to those
libraries using their interfaces instead of their concrete
implementation.
33. Inversion of Control (IoC)
IoC serves the following design purposes:
• To decouple the execution of a task from
implementation.
• To focus a module on the task it is designed
for.
• To free modules from assumptions about how
other systems do what they do and instead
rely on contracts (interfaces).
• To prevent side effects when replacing a
module.
33
34. Inversion of Control (IoC)
34
public class MvcDemoController : Controller
{
public ViewResult NewsOverview()
{
// Get news root item from Sitecore.
Item newsRoot = Sitecore.Context.Database
.GetItem("{NEWS-ROOT-GUID}");
IEnumerable<Item> newsItems = newsRoot.Children;
// Get temperature from weather service.
var weatherService = new WeatherService();
int temperature = weatherService.GetTemperature();
// Initialize model for News Overview page.
return this.View(new NewsOverviewModel
{
NewsItems = newsItems,
Temperature = temperature
});
}
}
35. Inversion of Control (IoC)
35
public class MvcDemoController : Controller
{
public ViewResult NewsOverview()
{
// Get news root item from Sitecore.
Item newsRoot = Sitecore.Context.Database
.GetItem("{NEWS-ROOT-GUID}");
IEnumerable<Item> newsItems = newsRoot.Children;
// Get temperature from weather service.
var weatherService = new WeatherService();
int temperature = weatherService.GetTemperature();
// Initialize model for News Overview page.
return this.View(new NewsOverviewModel
{
NewsItems = newsItems,
Temperature = temperature
});
}
}
TIGHT COUPLING
36. Inversion of Control (IoC)
36
public class MvcDemoController : Controller
{
private readonly ISitecoreContext sitecoreContext;
private readonly IWeatherService weatherService;
public MvcDemoController(ISitecoreContext sitecoreContext, IWeatherService weatherService)
{
this.sitecoreContext = sitecoreContext;
this.weatherService = weatherService;
}
public ViewResult NewsOverview()
{
// Get news root item from Sitecore.
Item newsRoot = this.sitecoreContext.ItemManager.GetItem("{NEWS-ROOT-GUID}");
IEnumerable<Item> newsItems = newsRoot.Children;
// Get temperature from weather service.
int temperature = this.weatherService.GetTemperature();
// Initialize model for News Overview page.
return this.View(new NewsOverviewModel
{
NewsItems = newsItems,
Temperature = temperature
});
}
}
37. Inversion of Control (IoC)
37
public class MvcDemoController : Controller
{
private readonly ISitecoreContext sitecoreContext;
private readonly IWeatherService weatherService;
public MvcDemoController(ISitecoreContext sitecoreContext, IWeatherService weatherService)
{
this.sitecoreContext = sitecoreContext;
this.weatherService = weatherService;
}
public ViewResult NewsOverview()
{
// Get news root item from Sitecore.
Item newsRoot = this.sitecoreContext.ItemManager.GetItem("{NEWS-ROOT-GUID}");
IEnumerable<Item> newsItems = newsRoot.Children;
// Get temperature from weather service.
int temperature = this.weatherService.GetTemperature();
// Initialize model for News Overview page.
return this.View(new NewsOverviewModel
{
NewsItems = newsItems,
Temperature = temperature
});
}
}
LOOSE COUPLING
38. Dependency Injection (DI)
There are several methods for DI,
some examples are:
• Constructor injection (as seen in the example)
• Parameter injection
• Setter injection
Use a framework that handles DI for you:
• Windsor container (because it ships with Glass)
• Ninject
• Autofac
38
39. MVC vs. WebForms
39
Why MVC is better
• Strict separation of responsibilities
• Simpler page lifecycle.
• Stateless (No more ViewState).
• No more server controls.
• Very easy to work with AJAX.
• Not bound to generated markup.
• Multiple forms on a page.
When to stick to WebForms
• Legacy application
• Team knowledge
• Prototyping
WebForms is just an extremely complex abstraction
over HTML/JS, invented before the introduction of
jQuery and AJAX;
We don’t need this abstraction anymore.
40. Join us!
Are you an awesome Sitecore Developer?
ParTech is looking for people to expand their team!
We offer you an excellent salary and benefits and
the chance to work on enterprise Sitecore projects
together with the most skilled developers available.
Join the Sitecore elite,
apply at www.partechit.nl !
40
41. References
• Follow me on Twitter:
@BrruuD
• Contact me by e-mail:
ruud@partechit.nl
• Read our blog:
www.partechit.nl/blog
41