How to use SignalR (and almost any third party library) in Kentico 8.2

   —   
In Kentico 8.2, it is easier to use third party libraries without getting into conflict with Kentico dependencies, as we will demonstrate by installing ASP.NET SignalR.

Short version

If you need to use a third party library and are just looking for a quick solution, please follow these steps:

  1. Open your Kentico solution.
  2. Exclude the CMSDependencies folder from the CMSApp project.
  3. Install the required NuGet package or add a reference to the required library to the CMSApp project.

In the case of ASP.NET SignalR (and other libraries that share dependencies with ASP.NET MVC) you first need to take these extra steps:

  1. Delete the Lib\MVC folder.
  2. Delete or upgrade the CMSApp_MVC project.

Please note that ASP.NET SignalR requires .NET Framework 4.5 or higher. Also, the instructions assume that you have installed Kentico as a web application project.

Using ASP.NET SignalR

ASP.NET SignalR is a library for developing web sites with real-time functionality. It allows bi-directional communication between the server and client. Servers can push content to connected clients instantly as it becomes available. The library requires .NET Framework 4.5 and a host application that supports OWIN.

There is a basic tutorial available as a part of the official documentation. If you follow this tutorial and install the Microsoft.AspNet.SignalR NuGet package into the CMSApp project, you will find out that Kentico does not run. You need to take a few additional steps as briefly described above:

  1. Delete the Lib\MVC folder. The folder contains an older version of ASP.NET MVC that is not compatible with the current releases of ASP.NET SignalR.
  2. Open your Kentico solution. To keep this example simple, I will assume that you do not have your own custom solution.
  3. Delete or upgrade the CMSApp_MVC project.If you do not use MVC, delete the CMSApp_MVC project from your solution. Otherwise, please upgrade to an MVC version that is compatible with the required version of ASP.NET SignalR. It is usually a safe bet to go with the latest versions.
  4. Exclude the CMSDependencies folder from the CMSApp project. This action is necessary to prevent the building process from using unwanted dependencies.
  5. Install the Microsoft.AspNet.SignalR NuGet package into the CMSApp project. This package contains the components necessary to implement server side functionality.
  6. Implement domain objects and hubs. If you follow the ASP.NET SignalR tutorial, you need to implement the ChatHub class.
  7. Implement SignalR initialization. Add a file with the following code into the CMSApp project. 
    using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(Startup), "ConfigureSignalR")] public static class Startup { public static void ConfigureSignalR(IAppBuilder app) { // Any connection or hub wire up and configuration should go here app.MapSignalR(); } }
  8. Implement client functionality. If you follow the ASP.NET SignalR tutorial, you need to create the index.html file.
  9. Build and run. You have successfully completed your task. 

Fixing a problem with deployment

Excluding the CMSDependencies folder has one drawback – it breaks the deployment process. If you publish the CMSApp project, it does not run because there are important dependencies missing.

To fix this problem, you need to extend the build process and collect additional files for deployment. Open the CMSApp project file for editing and locate the following import statements: 

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />

Add the following lines after the import statements: 

<PropertyGroup> <CopyAllFilesToSingleFolderForPackageDependsOn> CollectCMSDependencies; $(CopyAllFilesToSingleFolderForPackageDependsOn); </CopyAllFilesToSingleFolderForPackageDependsOn> </PropertyGroup> <Target Name="CollectCMSDependencies"> <ItemGroup> <_CMSDependencies Include="CMSDependencies\**\*" /> <FilesForPackagingFromProject Include="%(_CMSDependencies.Identity)"> <DestinationRelativePath>CMSDependencies\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath> </FilesForPackagingFromProject> </ItemGroup> </Target>

Running in Microsoft Azure

If you publish your application to Microsoft Azure, it will not run because there are important dependencies missing.

To fix this problem, you need to extend the build process and collect additional files for deployment. Open the CMSAzure.ccproj file for editing, locate the custom CMSPackToAzure tasks and add a new one to include the missing dependencies in the Azure package: 

<Target Name="BeforeAddRoleContent"> <CMSPackToAzure Destination="$(PackageObjFolder)CMSApp" Source="%(AdditionalSite.RootDir)%(Directory)$(AdditionalSitePublishDir)%(Filename)" /> <CMSPackToAzure Destination="$(PackageObjFolder)CMSApp\bin" Source="$(SolutionDir)CMS\bin" /> <CMSPackToAzure Destination="$(PackageObjFolder)SmartSearchWorker" Source="$(SolutionDir)Lib\Azure" /> <CMSPackToAzure Destination="$(PackageObjFolder)SmartSearchWorker" Source="$(SolutionDir)Lib" /> <CMSPackToAzure Destination="$(PackageObjFolder)SmartSearchWorker\CMSDependencies" Source="$(SolutionDir)CMS\CMSDependencies" /> <CMSPackToAzure Destination="$(PackageObjFolder)CMSApp\CMSDependencies" Source="$(SolutionDir)CMS\CMSDependencies" /> </Target>

You also need to be aware that when you scale out your application, your clients can get routed to different servers. Also, a client connected to one server will not receive messages from another server. There are several solutions available, e.g. forwarding messages between servers using a backplane.

A brief excursion back in time

When we wanted to include ASP.NET Web API in Kentico 8.1, we had a bit of a problem. If we referenced ASP.NET Web API from Kentico projects, we would force you to use exactly the same version of this library. The main reason is backward compatibility. As a new version of ASP.NET Web API might introduce breaking changes, you could not just replace one version with another because Kentico might stop working.

It was also not an option to start updating ASP.NET Web API regularly because that could break your application with every update. And this problem goes much deeper. If you installed a library that Kentico does not use, you might still break your application. It would only take a library that has a common dependency with Kentico, but references a different version of this dependency that is not compatible.

The common theme is that it is not possible to build and run an application that requires two incompatible versions of the same library. At least that is what we thought. But eventually we found a solution. Without getting into too much detail, we started hiding dependencies on third party libraries in Kentico. These libraries are still an internal part of Kentico, but they are not exposed and do not interfere with the building process.

As a result you are free to use almost any third party library you like without getting into conflict with Kentico dependencies. Please be aware that you might still get a dependency conflict between third party libraries, but now you can solve it without having a license to the Kentico source code.

Our plans for the future

There are still a few Kentico dependencies that remain exposed. You will probably not get in conflict with them, but to prevent any risk, we will remove them anyway. We will also fix the issues described in this article so you will be able to use third party libraries without any complications.

Share this article on   LinkedIn

Ales Kalina

Hi, I'm Product Architect at Kentico.

Comments