gRPC + ASP.NET Core as a Migration Path for WCFs in .NET Core

Premier Developer

Premier

App Dev Manager Keith Anderson and Field Engineer Patricio Belardo explore gRPC + ASP.NET Core as a migration path for WCF.

Overview

A recent statement from Microsoft’s Director of Program Management for .NET, Scott Hunter, regarding roadmap for .NET Core clarified the direction of Windows Communication Foundation (WCF) Services.

In his blog, Scott says, “After .NET Core 3.0 we will not port any more features from .NET Framework.” He also says, “If you are a remoting or WCF Server developer and want to build a new application on .NET Core, we would recommend either ASP.NET Core Web APIs or gRPC,…”

WCF had its faults, but it was clearly a wildly successful technology, as evidenced by the large library of services still in use.

The intended audience for this blog post is one who wants to migrate from the full .NET Framework to .NET Core and has a large library of WCFs, now considered technical debt, blocking the path to adoption.

This post will attempt to at least partially answer the question: How difficult will it be to migrate my current code base of WCFs to gRPC in .NET Core?

Comparison of WCF and GRPC

Whether or not gRPC is a viable migration path for your WCF services depends on how you are using WCF. GRPC is not a direct analog to WCF.

I haven’t seen a feature comparison matrix yet, so I thought I would take a stab at one.

FeatureWCFASP.Net Core + gRPC
PlatformsWindowsWindows, Linux, MacOS
ProtocolsLRPC/Named Pipes/HTTP/TCP/MSMQBinary (GRPC) + HTTP2

(TCP/Named Pipes/LRPC)

.AddProtocol(“ncacn_ip_tcp”, “8080”)

.AddProtocol(“ncacn_np”, @”\pipe\MyService”)

.AddProtocol(“ncalrpc”, “MyService”)

By removing the ASP.NET Core stack and just using .NET Core

Injected AspectsBehaviorsASP.NET Core DI Middleware/ gRPC interceptors
Distributed Transactions*Yes – [TransactionFlow], transactionscopes, and supported bindings*No
Transport SecuritySSL/TLSSSL/TLS
Message SecurityCertificates/credentialsCertificates/credentials

https://docs.microsoft.com/en-us/aspnet/core/grpc/authn-and-authz?view=aspnetcore-3.0

Windows AuthenticationKerberos/NTLMAAD Sync/ASFS + ASP.NET Core middleware
Proxies/ContractsService Contracts/Data ContractsProtocol Buffers
Proxy-less CommunicationWCF Channel Factory† Protobuf-Net.GRPC

*See Transactions below
†This is a 3rd party library and is not the solution formally supported by Microsoft.

Transactions

Just because you can do something, doesn’t mean you should, and in general, distributing database transactions across service calls is an anti-pattern to avoid. This was allowed in WCF, in situations where you had a client orchestrating calls to different services that each participated in part of a single atomic unit of work. All you needed was an ambient transaction scope and a binding that supported distributed transactions (NetNamedPipeBinding, NetTCPBinding, WSHttpBinding, etc.).

GRPC on the other hand, is just a communication channel and protocol. It does not concern itself with transactions at all.

If you cannot collect all of your database commits that constitute a unit of work in a single transaction, you may be forced to implement the compensating transaction pattern:

https://docs.microsoft.com/en-us/azure/architecture/patterns/compensating-transaction

This is anyway required for non-homogenous data repositories or data repositories that do not implement transaction coordination.

WCF distributed transactions will also not currently work with elastic transactions in the cloud, as .NET Core does not support them at the time of this writing. The full .NET Framework is required to implement elastic transactions and are limited to SQL Server as a Service in Azure. On premises or SQL Server in IaaS still requires the DTC.

Proxies/Contracts

WCF developers familiar with contract definitions should find gRPC protocol buffers to be the analogous construct serving the same purpose. The following shows an example of a WCF contract and a possible analogous protocol buffer:

For more information about protocol buffers, see the Protocol Buffer Language Guide: https://developers.google.com/protocol-buffers/docs/proto3

As you can see, this takes some re-writing and refactoring. The auto-generated classes need to be shared between server and client. They can be centralized and isolated for sharing to minimize the impact, but it is still impactful on developer time if you have a large library of WCFs to migrate.

Another option is to use the protobuf-net.grpc libraries which allow you to use the same declarative attributes as WCF contracts. This currently is not the formally supported method of creating GRPC services in .NET Core, though the protobuf-net.grpc library is a well-maintained 3rd party open-source project with close ties to the .NET Core team.

As you can see, if you had a WCF contract that looked like this, you could adopt a gRPC implementation through the protobuf-net.grpc library with no change to your code base.

Also, with WCF services, it was not necessary to generate a proxy class. Your client could use a ChannelFactory and the service definition itself to invoke the service. Using protobuf-net.grpc, this becomes the natural way to invoke the service, since you are sharing only the service contract definition.

Conclusion

By no means was this intended to be a comprehensive guide or step-by-step tutorial on migrating from WCF to gRPC+ASP.NET Core, but rather for the architect with large WCF technical debt, trying to decide what impact a migration might have to appropriately prioritize the work with upcoming projects, the hints that have been given should help provide a path forward.

There are analogs in an ASP.NET Core + gRPC solution to many, if not most of what WCF provides. For instance, gRPC interceptors or ASP.NET Core dependency injection can add the same functionality as custom WCF Service Behaviors.

If the codebase in question leverages the most common features of WCF and doesn’t stray too far into platform specific territory, and you are ok with introducing 3rd party open-source projects into your solution, it may be possible to migrate the entire codebase with minimal coding and just a few reference changes and recompilation.

References/Additional Reading

Premier Developer
Premier Developer

Premier Support for Developers

Follow Premier   

0 comments

    Leave a comment