Dependency Injection with WebAPI, Service Fabric and Autofac

Sample code

I really like the way Azure Service Fabric exposes actors and services from the factory as nicely typed interfaces in C#. It opens up some great scenarios for dependency injection and generally improving the developer experience.

To this end I decide to try and get Autofac going with the WebAPI Visual Studio template for Service Fabric.

The end goal is being able to pass services in like any other injected dependency like this:

private readonly IStateless1 _service;

public SomeRepo(IStateless1 service)
{
    _service = service;
}

public async Task<string> GetSomething()
{
    return await _service.GetHello();
}

You will need to install the Service Fabric SDK for this stuff.

Interestingly the template that is created when you add a WebAPI project to the Service Fabric project is not your traditional WebAPI affair – in this case we rely heavily on OWIN to build a self hosted WebAPI project almost from scratch (the template does handle most of this for you though).

When I saw the template generated code I feared that Autofac would not “just slot in” – it’s quite different to the regular WebAPI. That was not the case it turns out!

Because the WebAPI template makes great use of OWIN, the standard Autofac WebAPI Owin stuff worked pretty much straight away.

The magic happens in the Startup.cs file as per usual.

First you create a new ContainerBuilder and register the controllers.

 var builder = new ContainerBuilder();
 // Register your Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());    

The next code is from the template – create the HttpConfiguration and set up the MVC routes.

That config is then passed in to the Autofac extension to register the filter providers (so you can inject in to filters).

builder.RegisterWebApiFilterProvider(config);    

Now the fun part – registering our own services.

I created the amazingly named Stateless1 reliable service. It exposes IStateless1 which has the following method exposed on it:

public async Task<string> GetHello()
{
     return $"This is a test {DateTime.Now}";
}

I then register this using the overload of register that allows you to run some callback code lambda style.

builder.Register((e) => ServiceProxy.Create<IStateless1>(
     new Uri("fabric:/Application3/Stateless1")))
     .As<IStateless1>();

Once that is done, build the container and you’re set!

var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
appBuilder.UseWebApi(config);

I like to separate out my services a little bit from the code, even if that code is only referencing the interfaces so I’ve placed the actual access to the IStateless1 in to a repo that is my code (controllers) will access, rather than accessing the IStateless1 interface directly. This allows centralisation of the “SDK” to a library that other parts of your code can use.

public interface ISomeRepo
{
    Task<string> GetSomething();
}

public class SomeRepo : ISomeRepo
{
    private readonly IStateless1 _service;

    public SomeRepo(IStateless1 service)
    {
        _service = service;
    }

    public async Task<string> GetSomething()
    {
        return await _service.GetHello();
    }
}

https://github.com/jakkaj/AutofacServiceFabricExample/blob/master/src/WebApi1/Model/SomeRepo.cs

Note that IStateless1 is injected here. Once that is done, register the ISomeRepo with the container back in Startup.cs

builder.RegisterType<SomeRepo>().As<ISomeRepo>();

Finally – you can inject ISomeRepo in to your controller and start to see the results!

private readonly ISomeRepo _someRepo;

public ValuesController(ISomeRepo someRepo)
{
    _someRepo = someRepo;
}
// GET api/values 
public async Task<IHttpActionResult> Get()
{
    return Ok(await _someRepo.GetSomething());
}

Here is the full Startup.cs file

public static void ConfigureApp(IAppBuilder appBuilder)
{
    var builder = new ContainerBuilder();

    // Register your Web API controllers.

    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

    // Configure Web API for self-host. 
    HttpConfiguration config = new HttpConfiguration();    

    config.Routes.MapHttpRoute(

        name: "DefaultApi",

        routeTemplate: "api/{controller}/{id}",

        defaults: new { id = RouteParameter.Optional }
    );

    builder.RegisterWebApiFilterProvider(config);

    //Register the repo that our code will use to abstract the end code one level from the actor
    builder.RegisterType<SomeRepo>().As<ISomeRepo>();

    //Register the actor.
    builder.Register((e) => ServiceProxy.Create<IStateless1>(new Uri("fabric:/Application3/Stateless1")))
        .As<IStateless1>();

    // Set the dependency resolver to be Autofac.
    var container = builder.Build();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
    appBuilder.UseWebApi(config);
}

Full listing of https://github.com/jakkaj/AutofacServiceFabricExample/blob/master/src/WebApi1/Startup.cs

Building and Packaging .NET Core with AppVeyor

1 -> Experimenting with the Kudu API

2 -> Building and Packaging .NET Core with AppVeyor

3 -> Parsing command line arguments in .NET Core

I’ve been working on a project called k-scratch which allows remote logging and file sync with Kudu based sites – mainly for making local editing of Azure Functions easier.

As part of that I broke out the log stream component (called KScratchLog) in to a standalone console app. I plan to make this in to a broader console app that can get, push, log stream etc all from the command prompt… but before any of that can happen I figured I should get some CI going.

I decided on AppVeyor because it has .NET Core support, is free and works well with GitHub (like super well).

AppVeyor allows you to run PowerShell and CMD scripts, and the environments that builds are run in will be familiar to most .NET developers.

Most of the heavy lifting and config is done by placing an AppVeyor.yml script in the root of your GitHub Repo.

I had a hunt around, and saw that some projects use custom build scripts with AppVeyor in conjunction with the yml file, but I wanted to try and do it all in the yml.

Searching I found an example yml file by Steven Liekens that I used as a starting point.

Setting up the project.json files

I created my project in Visual Studio. It has a console app and a series of portable projects that are .NET Standard 1.3 based.

The first thing I had to do before I could get it to build on the command line using dotnet build was reference the dependency projects in the project.json file. Visual Studio did not do this automatically as it relies on the references in the .xproj files.

"dependencies": {
"Autofac": "4.1.0",
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
"NETStandard.Library": "1.6.0",
"System.IO": "4.1.0",
"System.Xml.XmlSerializer": "4.0.11",
"KScratch.Entity": {
"target": "project"
},
"KScratch.Contract": {
"target": "project"
}

The next step was making sure the build outputted .exe files, which it doesn’t by default. This is done in project.json.

Scott Hanselman’s post on self contained apps in .NET Core was a handy reference for this.

"runtimes": {
"win7-x64": {},
"osx.10.10-x64": {},
"ubuntu.14.04-x64": {}
}

Also make sure you reference the portable projects here too:

"frameworks": {
"netcoreapp1.0": {
"imports": "dnxcore50",
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.1"
},
"KScratch.Contract": {
"target": "project"
},
"KScratch.Entity": {
"target": "project"
},
"KScratch.Portable": {
"target": "project"
}
}
}

The final part of the story was getting the build to work. I played around on the command line on my local machine first to get it going before transporting the commands in to the build_script section of the AppVeyor.yml file.

I also added the ability to build separate platforms in the script, for now only windows is present.

Worth noting is that the AppVeyor platform would not support win10-x64 so I had to change it to win7-x64.

Once the build is completed and dotnet publish is called I package up the file using 7z, before referencing that zip as an artefact.

You can see a sample build output here and the resulting artefact here.

Finally – I went to the AppVeyor settings and got the MD for the all important AppVeyor build status badge and inserted it in my readme.md file!

Build status

Full AppVeyor.yml listing from here

version: '1.0.{build}'
configuration:
- Release
platform:
- win7-x64
environment:
  # Don't report back to the mothership
  DOTNET_CLI_TELEMETRY_OPTOUT: 1
init:
- ps: $Env:LABEL = "CI" + $Env:APPVEYOR_BUILD_NUMBER.PadLeft(5, "0")
before_build:
- appveyor-retry dotnet restore -v Minimal
build_script:
- dotnet build "src\KScratch.Entity" -c %CONFIGURATION% -r %PLATFORM%  --no-dependencies --version-suffix %LABEL%
- dotnet build "src\KScratch.Contract" -c %CONFIGURATION% -r %PLATFORM% --no-dependencies --version-suffix %LABEL%
- dotnet build "src\KScratch.Portable" -c %CONFIGURATION%  -r %PLATFORM% --no-dependencies --version-suffix %LABEL%
- dotnet build "src\KScratchLog" -c %CONFIGURATION% -r %PLATFORM% --no-dependencies --version-suffix %LABEL%
after_build:
- dotnet publish "src\KScratchLog" -c %CONFIGURATION% -r %PLATFORM% --no-build --version-suffix %LABEL% -o artifacts\%PLATFORM%
- 7z a zip\KScratchLog_%PLATFORM%.zip %APPVEYOR_BUILD_FOLDER%\artifacts\%PLATFORM%\*.*
#test_script:
#- dotnet test "src\KScratch.Tests" -c %CONFIGURATION%
artifacts:
- path: zip\**\*.*
cache:
- '%USERPROFILE%\.nuget\packages'
on_finish: # Run the demo to show that it works