2. Orchard 1
▪ Content Management System
▪ Inspired from Drupal and WordPress
▪ Super-extensible
▪ Not designed for anything else than web CMS
▪ Doesn’t integrate well into other apps
▪ Bootstrapped by black magic incantations
3. Orchard 1 subsystems
▪ Multi-tenancy + Dependency Injection
▪ Module system
▪ Event bus
▪ Themes & UI composition
▪ Runtime content-type system
▪ Extensible CLI and recipes
▪ Setup
▪ Warmup
▪ Users & Roles, Permissions
▪ Background tasks
▪ Workflow
▪ Media management
▪ Localization
▪ Cache
▪ Data access, database migrations
▪ Tokens
4. Orchard 2
▪ Rewrite
▪ Built on ASP.NET Core
▪ Designed to integrate into other applications, in parts or as a whole
▪ Even less coupling
▪ Same extreme extensibility
▪ Embraces document databases instead of relational
▪ 10x Orchard 1’s throughput
6. Multi-tenancy
▪ Improves site density
▪ Handles tenant-specific routes
▪ Scopes dependency injection and enabled features to the tenant
7. Module system
▪ Factors applications into single-responsibility subsystems
▪ Exposes services
▪ Dynamic compilation
▪ Local routing
▪ Features can be enabled and disabled
8. Event bus
▪ Decouples services
▪ Program against interfaces
▪ Interfaces are resolved by name
▪ Dynamic service resolution
▪ Really exchanges messages
▪ The base of Orchard extensibility
9. Themes and UI composition
▪ Shapes: dynamic view models
▪ Templates: views that render a shape
▪ Runtime template resolution
▪ Powerful system of alternate templates for specialized template overrides
▪ Placement: cooperative UI composition
10. Runtime content-type system
▪ Runtime types driven from code or metadata
▪ Types are composed from single-responsibility parts:
a blog post is made of a title, a slug/URL, a body, tags, and comments
▪ Any type can be modified
11. CLI & recipes
▪ Application command-line automation
▪ Thin shell
▪ Modules expose commands
▪ Model binding for the command-line
▪ Recipes: files containing custom commands (enable features, create content-
types, etc.), and import data
12. Setup
▪ Takes over requests for un-configured
shells
▪ Ask as little as possible up-front:
database engine, admin credentials, setup
recipe
▪ Defer as much as possible, make
decisions reversible
13. Warmup
▪ Serve statically-rendered pages while the app is warming up
▪ Pages that don’t have a pre-rendered version on disk will have to wait
▪ Orchard’s feature inspired the equivalent IIS feature
14. Users, roles, and permissions
▪ Pluggable authentication
▪ Decoupled users and roles
▪ Users are extensible content-types
▪ Modules expose permissions
▪ Permissions apply to roles
▪ Permissions are additive: no deny
▪ Single LoC permission checking
15. Background tasks
▪ HTTP favors fast and stateless operations
▪ Cleaning up, sending emails, long-running computations, all are best done in the
background
▪ Ideally, you’d have a separate service process and a message queue
▪ Next best thing is Orchard’s background task infrastructure
16. Workflow
▪ Makes processes pluggable and configurable
▪ An activity can be triggered by the output of another
▪ Manages processes that last for more than the request
17. Localization
▪ Standard po files
▪ All messages enclosed in a T():
@T(“This message needs to be localized.”)
msgctxt "~/Modules/Orchard.MediaPicker/Views/Fields/MediaGallery.cshtml"
msgid "No media. "
msgstr "Aucun média"
18. Data access & migrations
▪ Schema migrations (v1)
▪ Separation of storage and querying
▪ Pluggable storage providers
▪ Query on index
▪ Map/reduce-like pattern
20. Conclusion
▪ Many interesting subsystems that are not tied to content management
▪ Interesting architecture
▪ Largest OSS application built on .NET Core
Editor's Notes
Open startup.cs in clients/Orchard.Web, show the code. This is setting up a web host, then configuring it to find tenants, modules, and themes.
Instead, one could set-up everything by hand.
F12 on IServiceCollection, then on ServiceDescriptor
F12 on AddWebHost in startup.cs
Instead of having a fixed core bootstrapping modules and tenants, the “client” has been separated out, and is seen as just one way to build an app. You can replace it with your own. You can load a differently configured Orchard that searches for services somewhere else, or you can just include the services you want, or you could create your own middleware that lives right next to Orchard without interfering. You can choose the exact level of integration you want.
Site density: 700 blogs on a single Azure instance (4 web sites)
Dynamic compilation: important for edit / save / refresh development, just like on lesser platforms.
Template resolution: a shape needs to be rendered. We’ll try to resolve the template, so we’ll ask specialized services what theme should be used (theme resolution is pluggable like everything else), then we’ll look for a template in that theme. If we can’t find one, we’ll look in modules.
Alternates enable fine-tuning of the template resolution by enabling specialized templates to override the default one if certain conditions are met: you can build a little bit of code that detects that the user is authenticated for example, and add to the Login_status shape a Login_status_authenticated alternate. Then if there is a login-status-authenticated.cshtml template in the theme, it’ll be used over login-status.cshtml.
Placement: code can create and inject a shape into the existing UI tree with position information (zone “sidebar” with position “1.2.3”)
Any type can be modified: the module developer is in control of the part and its behavior, but not of the types that it’s composed into.
Setup recipe is a site archetype: default, blog, e-commerce, minimal, etc.
Not all applications start-up fast
Extensible users means trivial user profiles
Workflows are an example of operations that run as background tasks
No string identifiers: the default language string is it.