Book Image

Instant Nancy Web Development

By : Christian Horsdal
Book Image

Instant Nancy Web Development

By: Christian Horsdal

Overview of this book

Nancy is a C# web framework which aims to provide you ,the application developer, with an easy path to follow, where things will naturally fall into place and work. Nancy is a powerful, flexible, and lightweight web framework that allows you to get on with your job. Instant Nancy Web Development will give Readers practical introduction to building, testing, and deploying web applications with Nancy. You will learn how to take full advantage of Nancy to build clean application code, and will see how this code lends itself nicely to test driven development. You will also learn how to hook into Nancy to easily extend the framework. Instant Nancy Web Development offers you an in-depth exploration of all the major features of the Nancy web framework, from basic routing to deployment in the Cloud, and from model binding to automated tests. You will learn how to build web applications with Nancy and explore how to build web sites using Razor views. Next, you will learn how to build web based APIs suitable for JavaScript clients, mobile clients, and even desktop applications. In fact, you will learn how to easily combine the two into one. Finally, you will learn how to leverage Nancy to write clean and maintainable web applications quickly.
Table of Contents (7 chapters)

Hosting Nancy on the Cloud (Intermediate)


In this recipe, we take a look at how to host the application we have written so far on cloud services, such as on Windows Azure and AppHarbor. Both of these have PaaS solutions for running ASP.NET applications on their cloud infrastructure. In both cases, the application we've written so far is capable of running except for two things mentioned as follows:

  • The connection string for the data store has to be moved out of the code and into web.config. Hardcoding, as I have done so far, is a really bad idea, so moving the connection string to the web.config file is good anyway.

  • Avoid running the integration tests during the cloud build.

Getting ready

As always, we build on the code from the previous recipe, so just have that ready.

How to do it...

The following steps will help you host the application you built on cloud services:

  1. First go to AppHarbor (https://appharbor.com) and; just create an account with a free plan, since that should be fine for playing around with.

  2. Follow the instructions on the AppHarbor website to create an application, but do not deploy your Nancy application yet.

  3. Assuming that we are using MongoDB for the implementation of the IDataStore interface, add the MongoLab add-on to your AppHarbor application. This gives you access to a cloud-hosted MongoDB database that we will have our AppHarbor-hosted TodosNancy run against. If you have chosen another database for the data store, have a look through the AppHarbor add-ons—chances are there is an add-on for your type of database.

  4. Go to the web.config file in TodosNancy and add the following line to the application settings section:

      <appSettings>
        <add key="webPages:Enabled" value="false" />
        <add key="MONGOLAB_URI" value="mongodb://localhost:27017/todos"/>
      </appSettings>
  5. Then change the bootstrapper class to use this configuration value while connecting to the database as follows:

        protected override void ConfigureApplicationContainer(TinyIoCContainer container)
        {
          base.ConfigureApplicationContainer(container);
    
          var connectionString = ConfigurationManager.AppSettings.Get("MONGOLAB_URI");
          var mongoDataStore = new MongoDataStore(connectionString);
          container.Register<IDataStore>(mongoDataStore);
        }
  6. For all the tests to still pass, add an app.config file to the TodosNancyTests project and add the corresponding settings to it:

    <configuration>
      <appSettings>
        <add key="MONGOLAB_URI" value="mongodb://localhost:27017/todos"/>
      </appSettings>
    </configuration>
  7. The last piece missing before being ready to deploy this to AppHarbor is make sure the integration tests, that is, the tests in DocumentationTests and TodosModuleTest, are not run during the AppHarbor build and deploy pipeline. The reason for this is that we, on the one hand, want to take advantage of the fact that AppHarbor will run all unit tests it sees and only deploy if the tests pass, but on the other hand, we do not want to mess with setting up a test database on the cloud that can be used during test runs in AppHarbor. Note that if you use SQL Server for your data store, the xUnit AutoRollback attribute can be used to roll back changes made in tests. In real life scenarios (especially continuous delivery scenarios), though, you will probably want to do that test setup and have all the tests run in AppHarbor before deploying. To avoid running the integration tests on the cloud, first write an implementation of the ITestClassCommand interface in xUnit.net that only allows tests to run if they are running on a known developer machine and then apply it to the integration tests. The implementation is as follows:

      public class KnownDevMachinesOnly : ITestClassCommand
      {
        private TestClassCommand command;
        private ITypeInfo typeInf;
    
        public int ChooseNextTest(ICollection<IMethodInfo> testsLeftToRun)
        {
          return command != null ? command.ChooseNextTest(testsLeftToRun) : -1;
        }
    
        public Exception ClassFinish()
        {
          return command != null ? command.ClassFinish() : null;
        }
    
        public Exception ClassStart()
        {
          return command != null ? command.ClassStart() : null;
        }
    
        public IEnumerable<ITestCommand> EnumerateTestCommands(IMethodInfo testMethod)
        {
          return command != null ? command.EnumerateTestCommands(testMethod) : new ITestCommand[0];
        }
    
        public IEnumerable<IMethodInfo> EnumerateTestMethods()
        {
          return command != null ? command.EnumerateTestMethods() : new IMethodInfo[0];
        }
    
        public bool IsTestMethod(IMethodInfo testMethod)
        {
          return command != null ? command.IsTestMethod(testMethod) : false;
        }
    
        public object ObjectUnderTest
        {
          get { return command != null ? command.ObjectUnderTest : null; }
        }
    
        public ITypeInfo TypeUnderTest
        {
          get { return typeInf; }
          set
          {
            typeInf = value;
            if (KnowDevMachineNames.Contains(Environment.MachineName))
              command = new TestClassCommand(value);
          }
        }
    
        public IEnumerable<string> KnowDevMachineNames
        {
          get
          {
            yield return "HORSDAL";
            yield return "DEV2";
          }
        }
      }
  8. Then apply it to the tests by adding an attribute that indicates to xUnit.net that it should use our custom KnownDevMachinesOnly class when trying to run the tests as shown in the following code:

      [RunWith(typeof(KnownDevMachinesOnly))]
      public class TodosModuleTests
    
      [RunWith(typeof (KnownDevMachinesOnly))]
      public class DocumentationTests
  9. The only steps left now are to follow AppHarbors instructions on how to deploy the application. I will not repeat those here.

How it works...

AppHarbor is built for automatically running ASP.NET application. So, as long as our Nancy application is also an ASP.NET application, AppHarbor can run it. Since we have chosen to use the Nancy.Hosting.Aspnet NuGet package, our application runs on top of ASP.NET; so, from AppHarbor's standpoint, it is just an ASP.NET application.

There's more...

Nancy applications can also run easily on Windows Azure. With the slight modifications we have done in this recipe, the application is almost ready to run on Azure. The remaining bit is to make our application connect to the MongoDB document database once deployed to Azure. The easiest way to do this is to take advantage of Web.config transformations and add a Web.Release.config file containing the connection string to use in Azure. In fact, AppHarbor also supports Web.config transformations; so, this feature gives a solution that works in both cloud services.

Once the connection string issue is under control, just follow the instructions for deploying an ASP.NET MVC application to Windows Azure. The options for doing this include deploying from within Visual Studio using DropBox, TFS, Git, and more. All of these deployment paths work with Nancy applications too.