Though as a heavy WCF user in the past, I'd suggest your best bet is simply to throw out all your binding configs, and build your own REST API or similar backend (gRPC support in .NET 5+ is something often also recommended if you want something more RPC-like and need/want a more binary-serializer like approach, though in 2021 I'd just use JSON and something REST-ish myself). The nice thing about the Interface-driven "contract" approach should be that implementing your own is just a matter of implementing all your contract interfaces and injecting the physical implementations yourself.
I realize that can be easier said than done as things accidentally got coupled to very specific styles of bindings over the years and not everyone followed best practices and used the Async contracts so you have to tear out a bunch of synchronous faking code and wire back in Task<T>/ValueTask<T>. But generally, overall, the process was implement the interfaces and remove the "magic" in the process and I often found you end up with something better anyway because it is simpler and prone to less "magic" failures.
The easiest place to start with is your data contracts. You may not have many depending on which side of the RPC/not-RPC boundary you were on, but it may be as simple as creating plain classes that implement those data contracts and then double checking that the Newtonsoft.Json (classic) or System.Text.Json (newer, sleeker) JSON serialization looks nice, deserializes just fine. Generally this work is pretty straightforward and sometimes you can just eliminate the data contract interfaces when you are done (you won't likely need them anywhere else and most of their WCF-specific annotations may just be clutter at that point) and replace them with references to the "POCO" data classes.
Some of your service contracts you might also want to explore moving more of the arguments from lists of arguments into simple data classes that serialize nicely to JSON.
Then at a high level it's a matter of writing client side class implementations of your service contracts and server-side "proxies" that then call your existing server-side physical implementation of your service contract.
At a high level from the client side:
- Open a connection to the recipient
- Send the JSON serialized data to an endpoint
- Wait for the response
- Deserialize the response and return it
That's basically all that the "bindings" are doing for you in a magic nutshell. You'll just be writing it directly "by hand". In the case of a "REST-like" it would be using something like System.Net.Http.HttpClient on the client side and the HTTP method and your URLs would likely reflect your "operation contracts" (the names of the individual methods on your service contract): `Task<IMyItemDataContract> IMyServiceContract.GetItemDetails(int id)` to `http GET /api/item/details/{id}` for example type things. In general it's a lot of straightforward simple boiler plate to fill out for every interface method ("operation contract").
At a high level for the server side:
- Receive a connection
- Deserialize the data
- Call the appropriate service contract method
- Serialize and return the results
On the server side, for the simple "REST-like approach" you might want to build a simple ASP.NET (Core) host wrapper. These days you don't necessarily need the full weight of something like ASP.NET MVC and go do all the above steps with just what ASP.NET these days calls "Endpoint Routing".
Obviously complications come from figuring out your network topology shifts. Maybe you can't shift your "server" as easily to a real ASP.NET application hosted on a "real" HTTP server somewhere like IIS or Apache or whatever. In some of these cases you can find hints in your existing bindings. (Are you using MSMQ bindings? Use MSMQ or a modern direct replacement like Azure Storage Queues or redis instead of "REST-like" HttpClient and Server, for instance.) There are also ugly "duct tape" solutions such as ASP.NET's "Kestrel" web server can easily be hosted in other .NET processes, if it absolutely must remain an "ordinary" Windows Service or something crazy like that.
Once you prove that your "hand-written" clients and service endpoints work, you can generally just throw out most of WCF's binding gunk in your config files and all the attributes on your interfaces. A lot of your code shouldn't change that much in this whole process if it was already just calling the interfaces with again the big caveat being if you need to add Task<T> now, as opposed to having already migrated to it years ago or even using the older uglier Begin/End Async pattern which you often can easily replace with Task<T>).
Another option to possibly explore, depending on the nature of your ServiceContracts, how they are expected to feel ("real time?"), is to use SignalR rather than HTTP. (The basics are about the same: make sure everything serializes/deserializes JSON well and change your "operation contracts" to SignalR calls and event responses.) SignalR is also generally hosted on a webserver for negotiating match-making, but actual communications happen in "peer-to-peer" websockets generally after negotiations complete. Azure SignalR has some powerfully scalable hosted solutions, depending on your environment's tolerance for cloud-based tools.
The guy who wrote it talking about it: https://www.dotnetrocks.com/?show=1728
It emulates WebForms component with Blazor. Although I would just start from scratch.
Which is fine if you are a hobbyist developing for fun.
For some of us the "upgrade path" is impassable.
MS really made a grave mistake by coupling the evolution of the C# language to the .NET version. This means all projects on the .NET framework is now also stuck with an obsolete language version for no good reason.
It is becoming a a lot less fun to be a C# developer because you more often will have to work with obsolete tools.
gRPC is really fast and we have the WebForms monolith call into .NET Core services now so we can improve the back-end without dealing with so much ASPX crap.
For the most part that isn't true. You can use later C# compilers with older frameworks. Some features do, unavoidably, require framework support.
But that being said, the changes in C# aren't often that radical that I feel particularly constrained by older versions.
This
It’s not directly coupled, but each version of C# has a minimum .NET version it can support, due to the requirements of the features in the language itself (like LInQ in the past).
And MS has been very up front about .NET framework being legacy and not getting any future upgrades for years now.
Keeping every new C# feature compatible with every obsolete .NET version obviously has a big technical cost. MS has clearly decided it would rather spend its effort to improve C# for those keeping up to date.
> It is becoming a a lot less fun to be a C# developer because you more often will have to work with obsolete tools.
On the contrary. The language and platform is better to work with than ever and I can do everything I need, on Linux, with just Emacs and the CLI.
I couldn’t be happier!
Strawman there. The problem is not "every obsolete .NET version", the problem is .net in reality have two incompatible platforms at this point, but newer C# versions are only supported on one of them.
Going from framework to core will require (risky, expensive) rewrites, which means lots of real-world code will never be migrated. That is just reality. Startups who rewrite their whole tech stack every six months is not the norm outside of Silicon Valley.
So for the foreseeable future, .net will have these two platforms in parallel. And unless you are a hobbyist, you probably don't get to decide which one to use.
Microsoft have forgotten how important developer enthusiasm is for the success of a platform. Nobody likes to work on legacy code with obsolete tools with no end in sight.
But that’s fairly consistent right? An old platform not getting updates and a new platform getting updates?
Why would you expect the SDK of the officially deprecated platform to get updates with the latest compilers and technologies, but at the same time in every other way remain stagnant?
Microsoft has been very clear that what you have will keep working, but you won’t get any new toys.
If you want those, you have to put in the effort to upgrade your projects, and in worst case rewrite the portions you can’t.
> So for the foreseeable future, .net will have these two platforms in parallel.
Yeah. The old one not getting updated, used by those who won’t put in the effort to update their tools.
And the new one where all the nice things are happening, which really should act as a nice carrot, not a source of bitterness.
> Microsoft have forgotten how important developer enthusiasm is for the success of a platform.
99% of the old ASP.NET stack was terrible and unpleasant to work with.
The new stuff is nice (enthusiastic!) to work with exactly because they decided to not carry all that stuff forwards.
The new APIs was a nice fresh start for the current kind of apps one writes today.
I'm not sure what you mean with "consistent", but the problem is of course creating two incompatible platforms in the first place. All previous releases of .net have been largely backwards compatible (except for rare edge cases and security issues), so it remained a single platform where you could get the latest improvement just by upgrading the framework.
Of course when you have created two incompatible platforms, it would be double the work to keep both updated, so they have to abandon one. Which is why they shouldn't have done it in the first place. They could have upgraded and deprecated components in a modular manner without creating a whole separate incompatible platform.
Interest in .NET was dwindling because ... it was Windows-only and its APIs and frameworks was a bad fit for the cloud. It was literally heading for a nose-dive.
So if Microsoft wanted to address that and make .NET truly cross-platform, they either had 2 options: Port everything which is Windows-specific to all other platforms, or just strip it from the core .NET APIs.
If they wanted to make it more cloud friendly, again they had 2 options: Make the already complex APIs, even more complex by trying to shoehorn cloud use-cases into a BCL largely designed for a Windows AD-network kind of security model. Or just start over, with a clean slate, and APIs designed for the age we're currently writing software for.
While yes, the latter options creates a new incompatible platform, it's really the only realistic option. And if you're going for the first latter option, you might as well go for the second.
I don't think you will find anyone who believes Microsoft would be able to execute on .NET Core as it did, if it had tried to bring all the old legacy along for the ride.
> All previous releases of .net have been largely backwards compatible
Yes. Which has been a mixed blessing. Look at what a mess classic ASP.Net has become (which ASP.NET MVC is built upon) wrt to page-event life-cycles and what not. Are you not happy to see all that terrible things truly gone, for good?
> Which is why they shouldn't have done it in the first place. They could have upgraded and deprecated components in a modular manner without creating a whole separate incompatible platform.
But that's what they did, really.
They obsoleted classic ASP.NET and WebForms. They obsoleted WCF servers. And they obsoleted the Windows-centric security-model. Anything else?
Everything else is still there. The language, the rest of the BCL, the packages you know and love.
And you were given years after they said "These technologies are not getting any new updates" to migrate to the new ones (while still on classic .NET Framework), which was kindly published as multi-targeted Nuget-packages, to give you a gradual migration path.
Sure. It wasn't perfect, but what is?
If anyone is to blame here, it is how people have kept hanging on to classic .NET for years when the writing has been on the wall, hoping that maybe perhaps if they wait for another .NET Core release... That all those terrible technologies everyone is glad to let go off, will be ported to .NET Core too.
You know what? It didn't happen, because .NET Core was a community project, and the community didn't want it, or at least certainly not enough to warrant the effort.
And not only that! Thanks to being freed from the Windows it was borne into, it has become more vibrant and popular than ever before.
It's no longer a technology threatened with extinction. As someone using and invested in .NET yourself, surely you must appreciate that?
It is great that MS delivered a ground-up rewrite of ASP.NET. There is no reason this should cause the old ASP.NET framework to stop working. They could exist in parallel just like WPF and WinForms - one for new code, one for legacy code. Old libraries should just keep working by default.