OrchardProject + WebApi = interesting
Update: Code for the module is available on GitHub.
Orchard is really cool for CMS solutions, however, I am learning more about dependency injection, inversion of control, etc, and what I see in orchard is very interesting.
Asp.net mvc does well to de-couple pieces of the application when it comes to handling routes, but something is still missing. With asp.net mvc, you have to deploy these pieces along with the application, and perhaps discover them with mef, autofac, etc, but what about updates? If you wanted to update your modules, you have to FTP them to the application root, and re-write the dlls.
Is there an easier way to deploy updates, what about an application that could update itself????????
Nuget to the rescue
Phil Hack (@Haacked) wrote something on his blog about building a self-updating site using nuget (link.) This is really cool because it allows you to package up an application update, and the application can update itself.
However… the scenario I am going for is really about multiple modules.
Orchard CMS
Orchard uses Nuget, and is fully able to handle modules. From inside of the orchard application’s dashboard, I can install modules, as well as updates to those modules. The modules can also state dependencies, which are installed automatically.
Getting Started
To get started, first download an installation of Orchard CMS. I used the core recipe, as this is going to be more of a rest endpoint:
Then you will want to enable the code-generation module. Now you can create a module like using the orchard.exe command that should be in the bin folder of your application. I created a module called myRestfulModule:
Orchard just generated a module for us, and placed it in the /Modules directory inside the Orchard web application’s folder structure. This means that the module is already installed, just not yet activated.
I looked in visual studio, and my new module was not included automatically in the solution, so I added it. Here is my module: as you can see, it already has references to orchard dlls.
I tweaked the module.txt file to look something like this:
Name: myRestfulModule
AntiForgery: enabled
Author: Jeremiah Redekop
Website: http://blogs.geniuscode.net/JeremiahRedekop
Version: 0.5.0
OrchardVersion: 0.5.0
Description: A sample restful endpoint using wcfwebapi
Features:
myRestfulModule:
Description: Hello world using rest from inside orchard.
Which then gives Orchard the ability to render the module in the admin module library like this:
We can just go ahead and enable the module. Now let’s get the module doing something interesting. Go ahead and use nuget to install WebApi.All, which is good to start. (By the way, I started out with this tutorial on the orchard site, but had to tweak it to work with webapi.)
The details
We need to make a few tweaks:
- Orchard ROOT: Modify Web.config on Orchard application root – allow asp.net compatibility
- MODULE: Create Rest Endpoint – same as before with one tweak
- MODULE: Create Route Provider – helps orchard with routing requests to our module
Orchard Application Web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"></serviceHostingEnvironment>
</system.serviceModel>
This is the Rest endpoint. I am using the Fabricator library just to mock up a whole bunch of people. I need this class to implement IDependency for Orchard to create it properly
[ServiceContract]
public class PeopleService
: IDependency // required for orchard
{
private static readonly List _people = Fabrication.Fabricator.Generate(500).ToList();
[WebGet]
public IQueryable GetPeople()
{
return _people.AsQueryable();
//return new EnumerableQuery(new Person[]{});
}
[WebGet(UriTemplate = "{name}")]
public Person GetPerson(string name) {
return _people.Single(p=> p.Name == name);
}
}
Here is the route provider that uses the orchard convention of being at the root of your module. Orchard will use this to route requests to the rest endpoint. If you look at the extenson method, the goodies are there.
public class Routes : IRouteProvider {
private static readonly ServiceRoute _route = MapServiceRoute(typeof (PeopleService), "myRestfulModule/People");
public IEnumerable GetRoutes() {
return new[] {
new RouteDescriptor {
Priority = 1,
Route = _route
}
};
}
public void GetRoutes(ICollection routes) {
foreach (var routeDescriptor in GetRoutes())
routes.Add(routeDescriptor);
}
private static ServiceRoute MapServiceRoute(Type serviceType, string routePrefix, HttpConfiguration configuration = null, object constraints = null, bool useMethodPrefixForHttpMethod = true)
{
if (configuration == null)
configuration = new WebApiConfiguration(useMethodPrefixForHttpMethod);
var serviceHostFactory = new HttpServiceHostFactory { Configuration = configuration };
var webApiRoute = new WebApiRoute(routePrefix, serviceHostFactory, serviceType) { Constraints = new RouteValueDictionary(constraints) };
return webApiRoute;
}
}
Now by navigating to the url, you can see the end result.
Conclusion
This is a prototype of using an orchard module to expose rest endpoints. The main benefit, I believe, is the ability to expose and update endpoints independant of any application code. Once you deploy your orchard application, you don’t have to redeploy. All you have to do is publish updates to your modules, and then install them from the application’s admin panel.
There are downsides, such as having a dependency on Orchard, but the current release is production-ready.
















