I’ve written about plugins based on NuGet before. One piece of software that manages its pluggable parts with NuGet is Orchard – a CMS based on .NET and MVC, which from the experience of my company, Caliper, also serves as a nice framework for building web applications without any CMS functionality.
There’s a couple of things that Orchard solves for you, that make it great as a general framework:
- database connectivity (with NHibernate), including out-of-the-box support for local, automatic SqlCe databases,
- data migrations, for upgrading table schemas with new releases of your web applications or modules,
- theme and module management, with the use of NuGet packages and feeds,
- dynamic compilation, which lets you do in place changes to your web site or application, even through FTP, and see changes instantenously.
Orchard is distributed as a ZIP file that you can deploy as an application in IIS or open as a web application in Visual Studio. Module and theme packages are only managed through Orchard’s web UI, which gets them from a special Orchard Gallery Feed URL: http://packages.orchardproject.net/FeedService.svc
. If you open a module from that feed you’ll see that it contains all of its sources (as in *.cs files), for Orchard’s dynamic compilation to take care of. Open-source at its best. Or is it?
As much as we love having access to sources at Caliper, we love having them on-demand in our debugging sessions even more – instead of moving thousands of them around on disk for no reason. And we all have SymbolSource to handle that for free 🙂
So we set out to try and make Orchard and its modules more vanilla-nuggety and symbol/source server friendly.
Step 1: Packaging Orchard
First, we decided to try putting Orchard itself into packages. The end-result experience should speak for itself:
- Open Visual Studio and create an ASP.NET Empty Web Application (yes, no MVC, no Web Forms, no nothing).
- Add
http://nuget.gw.symbolsource.org/Public/Orchard/FeedService.mvc
as a new package source to Visual Studio (yes, SymbolSource can host and serve NuGet packages as a package repository) - Install the Orchard package from this feed in the empty project.
- Run the project with F5. You now have the Orchard setup page ready for action.
Things to note, as this should be considered work-in-progress still:
- All standard modules and themes are downloaded as dependencies. We haven’t tried yet to determine what subset is needed for setup, and which of them could be installed an on as-needed basis later with NuGet in Visual Studio or Orchard through the web UI.
- External dependencies are taken from the official NuGet feed only if they were taken by the Orchard team as-is, without modification or recompilation. All the rest is in Orchard.External.
- SqlCe native binaries are not included yet. But you should be good to go on your development machine, as you probably have in installed globally in your system.
- We haven’t yet figured out how to do versioning, so all packages have strict dependencies (==, i.e. [x.y.z] in NuGet).
- You can easily create your own binary module packages that take other Orchard modules as NuGet dependencies and get compiled with the right references.
Now for the best part:
- No *.cs files anywhere! Less files is more speed, less waiting, less transfers, less comparing on updates, less temptation to modify modules in place.
- Debuggable – with SymbolSource! All symbols (PDB files) and sources are indexed and accessible with Visual Studio using the regular, public SymbolSource URL. This applies only to
Orchard.Framework
,Orchard.Core
andOrchard.Web
projects at the moment, but all Orchard modules will follow soon. - No dynamic compilation! No more screwed up assembly names and WCF services unable to load. Yes, you can disable dynamic compilation in configuration, but then you’re still required to compile modules and cleanup sources yourself.
- All views are included in the main project as content files, so it’s easy to find, edit or copy them to your theme.
Step 2: Repackaging modules
Since a lot of the standard Orchard distribution is built using modules, we had to figure out how to transform them form source form into binary form. We have a small application that interfaces with NuGet and MSBuild to get the modules, guess their interdependencies from project references, then compile and repackage them. All of the standard modules have been uploaded in repackaged, binary form to the SymbolSource Orchard repository.
So far we haven’t touched any contributed modules from the Orchard Gallery, but our plan is to either create a SymbolSource gateway that would do that compilation on the fly (module authors would decide to push to it additionally), or monitor the gallery feed and repackage new modules into our Orchard repository automatically.
What do you think?
All the tooling that we created for this is available on GitHub: http://github.com/SymbolSource/Orchard. To run it, just clone, open a Visual Studio prompt and do msbuild Orchard.proj
. The output will be in pkg
(main Orchard packages) and pkgbin
(module packages).
Bertrand Le Roy (@bleroy)
/ October 2, 2012It sounds like a fun exercise but I fail to see the point. On a dev box, having the sources and being able to change them on the fly is preferable, so you don’t need this. On the production machine, you are going to deploy the whole application (and there are options do deploy just the binaries, without dynamic compilation), not module by module, so you don’t need it either.
TripleEmcoder
/ October 3, 2012In our experience this speeds up development really a lot. We actually don’t want to change Orchard’s sources in our applications, so this helps enforce the policy and lets the file system breathe a bit more.
As for contributed modules, we found that when two modules depend on each other, they don’t get downloaded automatically.
Also (although we haven’t tried this yet) this should make updates easier.
At some point we’ll try also compile views in, so modules would be basically single files, forcing our developers to override views in themes rather than modifying them in place.
I know, this might be a matter of style or taste. It’s just that this approach proved to be useful for us and we’d like to repackage future releases too. From the comments I see on Twitter it seems that a few other people would like Orchard packaged too 🙂
Bertrand Le Roy (@bleroy)
/ October 3, 2012I see, thanks for the answer. As you say, a question of taste. Sounds like a contribution that will be appreciated by some folks. Thanks!