Orchard Core and Service Fabric - Part 2 - Adding Orchard CMS

Adding Orchard CMS

Adding Orchard CMS to an existing ASP.NET Core project is already covered by Chris Payne in his Getting started with Orchard Core as a NuGet package post, so I won't repeat it here. Instead, here is a summary of what we need to do:

  1. Add a new NuGet source that points to https://www.myget.org/F/orchardcore-preview/api/v3/index.json.
  2. Add the OrchardCore.Applications.Cms.Targets package to the BooksUnlimited.Web project (make sure to check the "Include prerelease" checkbox!).
  3. Update the Startup class to add the OrchardCms middleware.

Adding the OrchardCore.Cms NuGet package to the ASP.NET Core project

Once the package is installed, open the Startup.cs file. We're going to replace the entire contents with the following code:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;

namespace BooksUnlimited.Web
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddOrchardCms();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseModules();
}
}
}

Pretty much the same result when you follow Chris' article, so that's cool.

However, there is one catch here that we should deal with now.

Adding support for Environment Variables

Notice the following line:

if (env.IsDevelopment())

That IsDevelopment() extension method takes a value from the launchsettings.json file for the IIS Express profile. However, our application is not launched by IIS Express, but by Service Fabric. Since Service Fabric uses a different way to provide configuration to our application, we need a way to supply Service Fabric configuration to our ASP.NET Core application. Fortunately, this is easy to do, since ASP.NET Core's configuration system is highly extensible. Let's see how this works.

Adding the ASPNETCORE_ENVIRONMENT environment variable

Each Service Fabric service project has a ServiceManifest, which is an XML file describing the service. This manifest supports an element called EnvironmentVariables, which is exactly what we shall use. The entire process is described in detail by Andrei Dzimchuk, so I will just describe the actual steps and you can read his excellent article for more detail. Go ahead and open ServiceManfest.xml (in PackageRoot of the BooksUnlimited.Web project), and locate the following section:

<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>BooksUnlimited.Web.exe</Program>
<WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>
</EntryPoint>
</CodePackage>

Now, add the following XML just before the closing </CodePackage> tag:

<EnvironmentVariables>
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="" />
</EnvironmentVariables>

Notice that we left the Value attribute blank. We will provide an actual value per environment using so-called application parameter files, and a default value on the ApplicationManifest.xml file. A parameter file allows us to provide configuration values per environment (e.g. develop, qa, stage, production).

Let's do this now and open the ApplicationManifest.xml file in the BooksUnlimited SF project in the ApplicationPackageRoot folder. Locate the ServiceManifestImport element, and add the following XML right before the closing </ServiceManifestImport> tag:

<EnvironmentOverrides CodePackageRef="Code">
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="[Environment]" />
</EnvironmentOverrides>

Finally, we need to add a Parameter named "Environment" to the Parameters element, since that's what we're referencing:

<Parameter Name="Environment" DefaultValue="Development"/>

The entire ApplicationManifest.xml file should look like this:

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="BooksUnlimitedType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Environment" DefaultValue="Development"/>
<Parameter Name="BooksUnlimited.Web_InstanceCount" DefaultValue="-1" />
</Parameters>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="BooksUnlimited.WebPkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides />
<EnvironmentOverrides CodePackageRef="Code">
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="[Environment]" />
</EnvironmentOverrides>
</ServiceManifestImport>
<DefaultServices>
<Service Name="BooksUnlimited.Web" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="BooksUnlimited.WebType" InstanceCount="[BooksUnlimited.Web_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
</ApplicationManifest>

Parameters can be substituted with per-environment values using application parameter files. You'll find a couple of them in the ApplicationParameters folder of the SF project.

In order for our ASP.NET Core application to be aware of these environment variables, we need to add a middleware component that does this for us provided by the Microsoft.Extensions.Configuration.EnvironmentVariables package. Go ahead and install that package into the BooksUnlimited.Web. When done, update the Startup class by adding the following constructor:

public Startup()
{
var builder = new ConfigurationBuilder()
.AddEnvironmentVariables();

Configuration = builder.Build();
}

And since we don't yet have a Configuration property, we should add that one as well:

public IConfigurationRoot Configuration { get; set; }

That's it! We should now be able to deploy and launch our application from Service Fabric and see Orchard's Setup page:

Go ahead and fill out the form and then hit Finish Setup.

I'm using SqlLite as the database type, which makes it easy for development purposes as I don't have to manually create any databases.

Once setup has completed, youshould be seeing a beautiful new website based on the Agency theme. The Agency theme is a package that was included when we installed the OrchardCore.Applications.Cms.Targets package.

And just like that, we have Orchard Core up and running in Service Fabric!

Being able to host Orchard Core in Service Fabric is really cool. But that's not the end of the story. Now that we're up there, we can take advantage of deep Service Fabric integration and start calling other services the Service Fabric way!

To demonstrate that, we will next create a service that we can call. See you at Part 3!

1 comment

  • ... Posted by Dean Marcussen Posted 07/26/2018 10:40 AM [https://www.everest-media.co.uk]

    Hi guys, always appreciated the great blogs.

    I've been trying to get this sample solution up and running with the newer beta of orchard (currently 1.0.0-betas-67855) on Azure Service Fabric 6.2.301 w/ dot net framework 4.7.2.

    I'm using services.AddOrchardCms(), and app.UseOrchardCore() as the newer way to bootstrap Orchard. This works fine in a none Service Fabric solution, but when I use it in a Service Fabric with the techniques outlined above I get a blank browser (no response at all).

    Any hints?

    Cheers, Dean

Leave a comment