Orchard 1.1: what's in it for developers?
My previous post focused on the most visible changes in Orchard 1.1 but we also made a few changes to the platform that open up new developer scenarios.
Suppressing Dependencies
Orchard is essentially built around the idea of dependency injection, but for those services that need to have a unique implementation, it was almost impossible to swap the default implementation with your own without hacking into our Autofac code.
With Orchard 1.1, you may now suppress a core dependency in order to substitute your own. Here is some code from Piotr's excellent Advanced Menu that uses that new feature:
namespace Szmyd.Orchard.Modules.Menu.Filters { [OrchardSuppressDependency("Orchard.UI.Navigation.MenuFilter")] public class MenuFilter : FilterProvider, IResultFilter {
I can't resist at this point but make this awful Mythbuster joke to convey the semantics of this:
namespace Adam.Savage { [OrchardSuppressDependency("YourReality")] public class MyOwn : IReality
Feature Priorities
One of the problems with event and handler processing in Orchard 1.0 was that the order in which multiple dependencies are registered was non-deterministic.
For example, in 1.1 we added a feature (Page Layer Hinting) that hints in a toast message whenever you create a page that you can create a widget layer for that page. The problem is that this handler needs to run after the RoutePartHandler has done its work (so we can get the right RoutePart.Path) but before Orchard.Widgets because of dependency order. This was done by giving the feature a priority of –1 in the module manifest:
Orchard.Widgets.PageLayerHinting: Name: Page Layer Hinting Description: Adds a notification after creating a new
Page with a direct link to create a Widget
Layer for that specific page by URL. Dependencies: Orchard.Widgets Category: Widget Priority: -1
WCF Services
When trying to expose an Orchard site's features as a WCF Services in 1.0, you were quickly faced with an impossible task: reconciling Orchard's constructor-based dependency injection with WCF parameterless constructors. This and other little problems.
In 1.1, you can create a SVC file using the new Orchard host factory:
<%@ ServiceHost Language="C#" Debug="true"
Service="MyModule.IMyService, MyAssembly"
Factory="Orchard.Wcf.OrchardServiceHostFactory, Orchard.Framework" %>
Then register your service normally as an IDependency but with service and operation contract attributes:
using System.ServiceModel; namespace MyModule { [ServiceContract] public interface IMyService : IDependency { [OperationContract] string GetUserEmail(string username); } }
In your implementation, you can now inject your own dependencies as you would normally from an Orchard service. No need for the contract attributes on that implementation.
Many thanks to André Rodrigues for providing much of the material for this post.