Service Fabric ASP.NET Core could not load file or assembly ServiceFabricServiceModel

After adding a reference to retrieve a Service Fabric Actor to my ASP.NET Core Web API project I got the following error when making the call to create the actor using IMyActor actor = ActorProxy.Create<IMyActor>(actorId, serviceuri);:

System.IO.FileNotFoundException: Could not load file or assembly 'ServiceFabricServiceModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
File name: 'ServiceFabricServiceModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
   at Microsoft.ServiceFabric.Services.Common.FabricServiceConfigSection.Initialize()
   at Microsoft.ServiceFabric.Services.Communication.FabricTransport.Common.FabricTransportSettings.LoadFrom(String sectionName, String filepath, String configPackageName)
   at Microsoft.ServiceFabric.Services.Communication.FabricTransport.Common.FabricTransportSettings.TryLoadFrom(String sectionName, FabricTransportSettings& settings, String filepath, String configPackageName)
   at Microsoft.ServiceFabric.Services.Communication.FabricTransport.Common.FabricTransportSettings.GetDefault(String sectionName)
   at Microsoft.ServiceFabric.Actors.Remoting.FabricTransport.FabricTransportActorRemotingProviderAttribute.CreateServiceRemotingClientFactory(IServiceRemotingCallbackClient callbackClient)
   at Microsoft.ServiceFabric.Actors.Client.ActorProxyFactory.CreateServiceRemotingClientFactory(Type actorInterfaceType)
   at Microsoft.ServiceFabric.Actors.Client.ActorProxyFactory.GetOrCreateServiceRemotingClientFactory(Type actorInterfaceType)
   at Microsoft.ServiceFabric.Actors.Client.ActorProxyFactory.CreateActorProxy[TActorInterface](Uri serviceUri, ActorId actorId, String listenerName)
   at Microsoft.ServiceFabric.Actors.Client.ActorProxy.Create[TActorInterface](ActorId actorId, Uri serviceUri, String listenerName)
   at Web.Controllers.Controller.<Create>d__1.MoveNext() in 

From this stackoverflow answer, it seems that there is currently an issue with the dotnet cli when working with nuget packages that do not explicitly reference assemblies. In this case, it is specifically an issue with Microsoft.ServiceFabric.Services package (version 2.0.217). When the ASP.NET Core publish action occurs, the ServiceFabricServiceModel.dll does not get copied to the publish folder but it is in the packages folder for the library.

Fixing with a postbuild script in project.json

This will likely be fixed but in the mean time you can fix this issue by adding a postbuild script in the ASP.NET Core RC2 project.json file. I used xcopy to copy the file from the packages folder to the publish directory. Once there, Service Fabric was able to package it up for deployment and everything worked.

In the project.json file add a scripts command:

{
  //...

  "scripts": {
     "postpublish": [ "xcopy ..\\packages\\Microsoft.ServiceFabric.Services.2.0.217\\lib\\net45\\ServiceFabricServiceModel.dll %publish:OutputPath%" ]
  }
}

This will locate packages folder (maybe different for your setup) and copy it to the output folder for the publish command.

Running Scripts Pre and Post Publish in ASP.NET Core RC2

This week I ran into an issue when deploying a Service Fabric service where a library file was not being copied to the output directory. Since I am using ASP.NET Core for my API layer in the Service Fabric project, I had to go dig around to figure out how to get the file to copy to the deployment folder during the publishing of the ASP.NET Core application.

note that this solution with project.json may change with as ASP.NET Core moves back to .csproj file

What I learned is that in ASP.NET Core RC 2 you can add scripts to the prepublish and postpublish events by adding a scripts section to the project.json file. In my case I needed to copy a file to the deployment folder after the rest of the project as built.

{
  "buildOptions": {
       // ...
    }
  },

  //...

  "scripts": {
    "prepublish": ["<command1>, <command2>"],
    "postpublish": [ "xcopy <pathtofile> %publish:OutputPath%" ]
  }
}

Note that you can reference variables like %publish:OutputPath%. You can also supply multiple commands by separating them with a comma. As noted above this currently works in ASP.NET Core RC2 but might change when as we transition back to the .csproj file.

Integrating ASP.NET Core with Service Fabric using ICommunicationListener

At the time of writing there is no official template for integrating ASP.NET Core (RC2) with Service Fabric in a Stateless Service so I though I would dive in and see if I could get it to work by looking at the ASP.NET 4.6 Web API Template that is currently available through Visual Studio. There will be a ASP.NET Core template available eventually but I thought this would be a useful exercise to learn more about how Service Fabric integrates with frameworks like ASP.NET.

You can find the full implementation of the solution I came up with on GitHub. There were also a couple examples that I used for reference. The first was a really basic template on GitHub which I used as my starting point to creating an ASP.NET Core Communication Listener. The other was the more advance solution that shows not only how to integrate but also build an API Gateway after the Microservices Gateway pattern.

ICommunicationListener

Lets take a look at the Service Fabric’s ICommunicationListener interface which provides a few basic benefits.

First, it allows for service communication in an agnostic manner. This means you can communicate with HTTP, UDP, or another other custom protocol you might need for your application by implementing this interface. You can even communication with more than one protocol for one service.

Another benefit it offers is allowing for your service to be moved without affecting any clients that are working with it. Any given service can move to another server because of machine failure, upgrade, resource balancing, etc., causing a change in the IP address of the actual service. By implementing this interface you are saved from having to manage any of those situations, instead Service Fabric manages it for you.

The ICommunicationListener interface accomplishes this by registering your service with the Service Fabric Naming Service which will then keep track of the endpoint locations where the services are located. This means a client can ask the Naming Service for a service by name and will be given the correct address without the need to know which machine it is actually running on (think along the same lines as DNS).

It achieves this through a simple interface ICommunicationListener which has three methods:

  • Abort - exit immediately, cancelling current requests
  • CloseAsync - stop taking any new requests, close current requests gracefully and then exit
  • OpenAsync - Open listener to be able to accept and send messages

As you can see it is a fairly simple interface but is a power concept because of the ability to allow for any type of communication and even multiple protocols per service.

Building an ASP.NET Core Communication Listener

The first method we will implement is the OpenAsync Method. In the case of the ASP.NET Core Communication Listener, this method will be responsible for starting the web service and binding it to the correct URL. But first we need to gather some information about where the service is running from Service Fabric.

Gathering Service Fabric Information

Since our service could be running on any server inside our cluster we need to get some of this information from Service Fabric runtime. We use the FabricRuntime class to get the CodePackageActivationContext and NodeContext which contains information like the current service protocol, current IPAddress, and port. We can get this information and format it appropriately by doing the following:

var endpoint = FabricRuntime.GetActivationContext().GetEndpoint(endpointName);

string serverUrl = $"{endpoint.Protocol}://{FabricRuntime.GetNodeContext().IPAddressOrFQDN}:{endpoint.Port}";

The endpointName variable is being passed in from the initial creation of the service in the program.cs file. It is any arbitrary name you decide to give the service. Take a look at how this all come together in the full solution on the GitHub repository.

Starting ASP.NET

At it’s heart ASP.NET Core is actually a command line console application. To start an ASP.NET application we use the WebHostBuilder class. You can find an implementation of this in the ASP.NET Core RC2 template that ships with Visual Studio. We are going to use slightly different setup than that template; The main differences are that we don’t need to use IIS Integration and we need to specify the serverUrl that we just generated with the Service Fabric runtime information:

var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .UseUrls(serverUrl)
                .Build();

host.Run();

Implementing Open

Now that we know have the current URL of the service and know how to start the ASP.NET server, we can finish our implementation of the OpenAsync method.

This is just bringing together the previous two pieces and returning a server Url as a string. The return value of the OpenAsync method will be the address that is registered with the Service Fabric Naming Service allowing for the service to move around in the case of machine failure, upgrades, etc.

Here is what the whole OpenAsync Method looks like:

 public Task<string> OpenAsync(CancellationToken cancellationToken)
{
    var endpoint = FabricRuntime.GetActivationContext().GetEndpoint(endpointName);
    string serverUrl = $"{endpoint.Protocol}://{FabricRuntime.GetNodeContext().IPAddressOrFQDN}:{endpoint.Port}";


    webHost = new WebHostBuilder
                    .UseKestrel()
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseStartup<Startup>()
                    .UseUrls(serverUrl)
                    .Build();

    webHost.Start();

    return Task.FromResult(serverUrl);
}

Implementing Abort and Close

We still need to implement two more methods on the ICommunicationListener before we are finished: Abort and CloseAsync. These are fairly simple implementations and just require us to dispose of the WebHost object. You could get fancier and make sure all requests are handled but for right now we will just shut down the web service as that is what is done in the ASP.NET Web API template currently.

public void Abort()
{
    if (webHost != null)
    {
        webHost.Dispose();
    }

}

public Task CloseAsync(CancellationToken cancellationToken)
{
    if (webHost != null)
    {
        webHost.Dispose();
    }

    return Task.FromResult(true);
}

Register the Asp.Net Core Communication Listener with Service Fabric

We have created the Asp.Net Core Communication Listener but still need to register it with the StatelessService that will be using ASP.NET. There is a method on the StatelessSerivice Class that you can overload to return make the connection.

This is the integration point between Service Fabric and Asp.Net. In the case of Stateless service this returns the an array of ServiceInstanaceListners.

In the StatelessService class, override the CreateServiceInstanceListeners:

internal sealed class WebHostingService : StatelessService
{
    private readonly string _endpointName;

    public WebHostingService(StatelessServiceContext serviceContext, string endpointName)
        : base(serviceContext)
    {
        _endpointName = endpointName;
    }

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new[] { new ServiceInstanceListener(serviceContext => new AspnetCoreCommunicationListener(_endpointName)) };
    }
}

Next steps

This is a simple implementation of an Asp.net Core Communication Listener for Service Fabric. If you would like to see the full working sample, check out this GitHub repository. I have implemented everything we talked about but also started to add in the ability to unit test the AspNetCoreCommunicationListener.

Eventually there will be a template that Visual Studio will ship with that will provide a default implementation. The defualt will be a likely good choice for getting started but this exercise of working through how to implement a ICommunicationListner is a good introduction to the ICommunicationListener interface and helps us better understand another aspect of the Service Fabric platform.

Starting the Service Fabric Local Cluster Manager

I have had to start the Service Fabric Cluster Manager a few times without starting Visual Studio and deploying the application for talks or demos. Since the Cluster Manager is a separate process there is no need to run Visual Studio, simply:

  1. Open the Windows Run Dialog (Windows Key + R)
  2. Type ServiceFabricLocalClusterManager.exe and hit OK

Now your local Service Fabric Cluster is running and you can navigate to any endpoints you have exposed.

5 Ways to Install Git on Windows

Git is a major part of a developers work flow these days no matter what platform you work on. There are many different ways to install and use Git on Windows and in this post I will cover 5 different ways and talk about the pro’s and con’s of each. At the end you should have a good idea of how to have a great experience with Git on Windows not matter what your scenario. Be sure to let me know your favorite in the comments or if I missed one.

There is a walk through video for each of the ways to install git on Windows coming soon.

The Five ways

Below are the 5 basic ways to install git on Windows. There are probably others but these are the ones that I tend to show developers. I personally tend to end up installing git for command line usage and installing a GUI for more complex tasks. There are a few tasks (sqaushing commits) that are easier on the command line and a few that are easier in a GUI (selecting single lines from multiple changes in a file for an atomic commit).

  1. Git for Windows
  2. Using Chocolatey - preferred way on Windows 10
  3. Using Cmder - Great for older version of Windows
  4. Your Favorite Git GUI - Visual Studio, Sourcetree, GitHub Desktop, GitKraken, etc
  5. Bash on Windows - In preview for Windows 10 (sign up for the Windows Insider to try it out today)

Git for Windows

Git For Windows is the foundation for running Git on Windows. Many of the other options listed are using Git for Windows (previously msygit) under the hood. This option will install the git client, the windows implementation of BASH tools and a few Git GUI tools. If you want just the raw tools then this is the installer for you. If you want some more advance tooling then look to some of the other options. I generally prefer to install this via a different option.

You can install it from Git for Windows.

Pro’s

  • basic tooling
  • shell integration (right click to open BASH Promp / GUI)

Con’s

  • GUI is old school
  • BASH tools are only available in BASH prompt by default
  • confusing installer with lots of options

Using Chocolatey

This is my preferred way to install the Git for Windows on Windows 10. It installs the same package before but in one line. If you have not heard of Chocolatey stop everything and go learn a bit more. Chocolatey can install the software with a single command; you don’t have to use click-through installers any more! If you are coming from Linux think of it as the apt-get/yum for Windows. Chocolatey is very powerful and I use it in combination with Boxstarter to set up my dev machines. If you are in charge of setting up machines for developers on windows it is definitely worth a look.

I love this option because it is fast to set up (one liner) and with Windows 10’s new command console (it resizes and has copy/paste) I get the a great native experience. Using keyboard shortcuts (Windows key + X then C), I can have a command prompt open quickly and start using git right away. Watch the video to see another cool trick where you can open the command window in any open folder.

Let’s see how you would install git using Chocolatey. I assume you have Chocolatey installed already (it is a one liner in the command prompt). Then simply open Administrator Command Window and type:

choco install git -params '"/GitAndUnixToolsOnPath"'

This will install git, the BASH tools and add them to your path.

Pro’s

  • fast setup
  • use existing Windows 10 command prompt for native experience

Con’s

  • if done on older version of windows the command prompt experience is poor
  • have to have Chocolately installed (though really easy to set up and over all awesome tool)

Using Cmder

This was my go to option before Windows 10 and would be what I recommend for anyone not using Windows 10. The command line experience in older versions of Windows is poor (no resize/copy paste) and Cmder brings together a set of awesome tools to make a great command line experience. I always choose the larger install option, as it comes with git (again Git for Windows) and the BASH tools all hooked up. Some of the other features it brings along are portability (which is great if you are running events), keyboard shortcuts like copy and paste, easy aliasing, and more.

You install it by downloading the “Full” option on the Cmder page.

Pro’s

  • portable
  • brings copy/paste, resizing and more options to command prompt in older versions of Windows
  • nice looking prompt

Con’s

  • emulator (no quick shortcuts to open without other tools, can be less responsive)

Your Favorite Git GUI

I don’t want to get into the battle of the best GUI for git as they all have pros and cons. The key here is that all of them come with git installed. If you a fan of GUI’s or just getting started this is great place to get started as you don’t have to worry about the command line or setting up command PATH’s.

I tend install git via Chocolately then use a GUI for my day to day work. That said, I usually use the right tool for the right job when it comes to GUI vs command line. Some scenarios I really enjoy using the GUI are when viewing complex diff’s or helping make atomic commits (I made more than one change because I got carried away and want to commit then one at a time ;-) ).

I don’t have a section on installing the GUI’s in the video as there are to many to show, each one is behaves differently and are relatively easy to install and set up.

Pro’s

  • easy guided git experience through GUI
  • no need to mess with PATH and other tooling

Con’s

  • git not usually added to PATH (can’t kick over to command line when
  • everyone prefers a different UI and may not know how to use yours

Bash on Windows

This is one of the more promising solutions for the future. At the time of writing, it is in preview on the Fast ring of the Windows Insider program. I talk about why this is a promising solution on my Thoughts on Build 2016 post along with a demo. This allows us to run git directly on BASH on Ubuntu on Windows. This means that we are not using a Windows implementation of BASH but the real BASH. More in-depth details on the from the developers themselves can be found at the discussion on Linux Command Line on Windows. This option is going to be really exciting for open source projects where developers might work on a variety of platforms.

The set up for this requires you to be on the Windows Insider program at the time of writing. Once you have the latest insider build installed you can follow the instructions at https://blogs.msdn.microsoft.com/commandline/2016/04/06/bash-on-ubuntu-on-windows-download-now-3/.

Pro’s

  • real BASH and git
  • it is the real BASH!
  • fast

Con’s

  • still in preview
  • requires the insider preview build

Conclusion

There are many options for getting Git install on Windows to create a great experience no matter what your requirements are. As with any choice there are trade off’s depending on your specific scenario so try a few of the options out and find the one that works best for you. Did I miss one? What is your favorite? Let me know in the comments below.