CoherentSolutions.Extensions.Hosting.ServiceFabric is an extension to existing HostBuilder. The idea is to simplify configuration of Reliable Services by removing unnecessary code and improving separation of concerns.
As usual, the easiest way to get started is to code → a new Reliable Service!
NOTE
This section doesn't present and explains all features / aspects of the CoherentSolutions.Extensions.Hosting.ServiceFabric. The complete documentation is available on project wiki.
In this section we will:
- Configure one stateful service
- Configure three endpoints (by configuring three listeners: ASP.NET Core, Remoting and Generic)
- Configure one background job (by configuring a delegate to run on
RunAsync
lifecycle event).
All programs start from entry point and so do Reliable Services. When using CoherentSolutions.Extensions.Hosting.ServiceFabric application entry point starts with new instance of the HostBuilder class followed by calls to Build()
and Run()
methods.
private static void Main(string[] args)
{
new HostBuilder()
.Build()
.Run();
}
Reliable Service's configuration is done within configuration action accepted by DefineStatefulService(...)
or DefineStatelessService(...)
extension methods.
NOTE
You can find more details on defining services wiki page.
private static void Main(string[] args)
{
new HostBuilder()
.DefineStatefulService(serviceBuilder => { })
.Build()
.Run();
}
The first step when configuring a service (no matter stateful or stateless) using CoherentSolutions.Extensions.Hosting.ServiceFabric is to "link" configurable service to one of the ServiceTypes declared in the ServiceManifest.xml
.
<ServiceManifest Name="ServicePkg" Version="1.0.0">
<ServiceTypes>
<StatefulServiceType ServiceTypeName="ServiceType" HasPersistedState="true" />
</ServiceTypes>
</ServiceManifest>
The "link" is create using UseServiceType(...)
method.
private static void Main(string[] args)
{
new HostBuilder()
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder.UseServiceType("ServiceType");
})
.Build()
.Run();
}
This code is now ready to run. CoherentSolutions.Extensions.Hosting.ServiceFabric will do all the plumbing required to start the service.
Unfortunatelly it's current implementation is empty and does nothing.
Reliable Services can expose endpoints. This exposure is represented in form of listeners configured on replica startup. The CoherentSolutions.Extensions.Hosting.ServiceFabric provides a simple way to configure: ASP.NET Core, Remoting listeners and Generic listeners.
All listeners are configured using the same flow as was demonstrated for services.
NOTE
You can find more details on defining listeners wiki page.
ASP.NET Core listener configuration starts with a call to .DefineAspNetCoreListener(...)
method. This method accepts an action where all listener specific configuration is done.
private static void Main(string[] args)
{
new HostBuilder()
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder
.UseServiceType("ServiceType")
.DefineAspNetCoreListener(listenerBuilder => { });
})
.Build()
.Run();
}
The listener should be linked to one of the endpoint resources defined in the ServiceManifest.xml
.
<ServiceManifest Name="ServicePkg" Version="1.0.0">
<Resources>
<Endpoints>
<Endpoint Name="ServiceEndpoint" />
</Endpoints>
</Resources>
</ServiceManifest>
The linkage is done using UseEndpoint(...)
method.
private static void Main(string[] args)
{
new HostBuilder()
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder
.UseServiceType("ServiceType")
.DefineAspNetCoreListener(
listenerBuilder =>
{
listenerBuilder.UseEndpoint("ServiceEndpoint");
});
})
.Build()
.Run();
}
The listener is an infrastructure wrapper around the configuration process of IWebHost
. The IWebHost
configuration is done in ConfigureWebHost(...)
method.
private static void Main(string[] args)
{
new HostBuilder()
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder
.UseServiceType("ServiceType")
.DefineAspNetCoreListener(
listenerBuilder =>
{
listenerBuilder
.UseEndpoint("ServiceEndpoint")
.ConfigureWebHost(webHostBuilder => { webHostBuilder.UseStartup<Startup>(); });
});
})
.Build()
.Run();
}
Remoting listener has slightly different configuration curse than ASP.NET Core listener. The configuration starts from the call to DefineRemotingListener(...)
and UseEndpoint(...)
methods.
private static void Main(string[] args)
{
new HostBuilder()
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder
.UseServiceType(...)
.DefineAspNetCoreListener(...)
.DefineRemotingListener(
listenerBuilder =>
{
listenerBuilder
.UseEndpoint("ServiceEndpoint2");
});
})
.Build()
.Run();
}
The remoting implementation consists from two parts: remoting interface and remoting implementation.
remoting interface defines the API surface...
public interface IApiService : IService
{
Task<string> GetVersionAsync();
}
... while remoting class implements the API.
public class ApiServiceImpl : IApiService
{
public Task<string> GetVersionAsync()
{
return Task.FromResult("1.0");
}
}
Remoting implementations is configured using UseImplementation<T>(...)
method.
private static void Main(string[] args)
{
new HostBuilder()
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder
.UseServiceType(...)
.DefineAspNetCoreListener(...)
.DefineRemotingListener(
listenerBuilder =>
{
listenerBuilder
.UseEndpoint("ServiceEndpoint2")
.UseImplementation<ApiServiceImpl>();
});
})
.Build()
.Run();
}
Generic listener allows custom listeners to be configured using the same approach as DefineRemotingListener(...)
and DefineAspNetCoreListener(...)
.
private static void Main(string[] args)
{
new HostBuilder()
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder
.UseServiceType(...)
.DefineAspNetCoreListener(...)
.DefineRemotingListener(...)
.DefineGenericListener(...)
listenerBuilder =>
{
listenerBuilder
.UseEndpoint("ServiceEndpoint3")
.UseCommunicationListener(
(context, name, provider) =>
{
return /* ICommunicationListener */;
})
});
})
.Build()
.Run();
}
In CoherentSolutions.Extensions.Hosting.ServiceFabric background jobs and event handlers are represented in form of Delegates. The Delegate is configured using DefineDefine(...)
method.
You can find more details on defining delegates wiki page.
private static void Main(string[] args)
{
new HostBuilder()
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder
.UseServiceType(...)
.DefineAspNetCoreListener(...)
.DefineRemotingListener(...)
.DefineDelegate(delegateBuilder => { });
})
.Build()
.Run();
}
The action to execute is configured by calling UseDelegate(...)
method with accepts any Action<...>
or Func<..., Task>
compatible delegate.
private static void Main(string[] args)
{
new HostBuilder()
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder
.UseServiceType(...)
.DefineAspNetCoreListener(...)
.DefineRemotingListener(...)
.DefineDelegate(
delegateBuilder =>
{
delegateBuilder.UseDelegate(async () => await Database.MigrateDataAsync());
})
})
.Build()
.Run();
}
That is it :)
For project documentation please refer to project wiki.
For information on past releases please refer to version history page.
For additional information on how to contribute to this project, please see CONTRIBUTING.md.
- Configuring Service
- Configuring Multiple Services
- Configuring Custom Service Event Source
- Using Hierarchical Dependency Registration
- Reacting On Service Lifecycle: Routine Events
- Reacting on Service Lifecycle: Package Events
- Using Local Runtime for Debugging
This project is owned and maintained by Coherent Solutions.
This project is licensed under the MIT License - see the LICENSE.md for details.
Besides this project Coherent Solutions also maintains a few more open source projects and workshops:
Projects
- service-fabric-run-tests - is a Docker image designed to run Service Fabric oriented unit-tests (.NET Core) on Linux.
- CoherentSolutions.Extensions.Configuration.AnyWhere - is an extension to Microsoft.Extensions.Configuration. This extension allows application to configure it's configuration sources using environment variables.
Workshops
- Building Self-Driving Car Architecture with Robot Operating System - is a workshop to introduce attendee to Robot Operating System (ROS) design and create simple self-driving car architecture.