1
votes

Am exploring the Service Fabric Microservices functionality of Azure and liking it a lot. I have hosted some simple WCF services there and I can call those services from .NET Framework clients using the WcfClientCommunicationFactory class. All works well.

Now I want to call my microservices from a .NET Core console app. Search results for those keywords are skewed to towards using .NET Core to implement the actual service, but I want to use .NET Core for the client.

Can .NET Core apps talk to Service Fabric Microservices yet? If so, what's the .NET Core equivalent of WcfClientCommunicationFactory?

1
Might this blogs.msdn.microsoft.com/webdev/2016/06/26/… be of any help? Easiest way is to use stateless apis that call the wcf services in the cluster. client can than connect using rest.Peter Bons

1 Answers

1
votes

Right name for the factory is WcfCommunicationClientFactory, which is located in Microsoft.ServiceFabric.Services.Communication.Wcf.Client namespace from Microsoft.ServiceFabric.Services.Wcf NuGet package. But it's not compatible with .Net Core for now, as whole WCF approach and Service Fabric aren't.

Service Fabric Microservices is a REST-services in the end, so you have three methods to host it (from MSDN):

  • No specific protocol: If you don't have a particular choice of communication framework, but you want to get something up and running quickly, then the ideal option for you is service remoting, which allows strongly-typed remote procedure calls for Reliable Services and Reliable Actors. This is the easiest and fastest way to get started with service communication. Service remoting handles resolution of service addresses, connection, retry, and error handling. This is available for both C# and Java applications.
  • HTTP: For language-agnostic communication, HTTP provides an industry-standard choice with tools and HTTP servers available in many different languages, all supported by Service Fabric. Services can use any HTTP stack available, including ASP.NET Web API for C# applications. Clients written in C# can leverage the ICommunicationClient and ServicePartitionClient classes, whereas for Java, use the CommunicationClient and FabricServicePartitionClient classes, for service resolution, HTTP connections, and retry loops.
  • WCF: If you have existing code that uses WCF as your communication framework, then you can use the WcfCommunicationListener for the server side and WcfCommunicationClient and ServicePartitionClient classes for the client. This however is only available for C# applications on Windows based clusters. For more details, see this article about WCF-based implementation of the communication stack.

Note: You need ASP.NET Core tools for Visual Studio 2017. The .NET Core tools for Visual Studio 2015 are no longer being updated.

Note #2: While ASP.NET Core apps can run on .NET Core or on the full .NET Framework, Service Fabric services currently can only run on the full .NET Framework. This means when you build an ASP.NET Core Service Fabric service, you must still target the full .NET Framework. So none of NuGet packages from Service Fabric are targeted to full .NET Framework.

ASP.NET Core app can be hosted as a guest executable on Service Fabric with no code changes, but the recommended way to do that is to hosting ASP.NET Core in a Reliable Service with Kestrel (NuGet package) or WebListener (NuGet package):

enter image description here

After you publish your server in Service Fabric, you can connect to it using HTTP protocol from anywhere - Web Frontend, Angular SPA, Xamarin or simple C# HttpClient, so client doesn't need to be targeted to full .NET Framework, but server is.

Some sample code:

static HttpClient client = new HttpClient();

client.BaseAddress = new Uri(MICRO_SERVICE_URI);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
    // deserialize the result from JSON
    var result = await response.Content.ReadAsAsync<DtoClass>();
}