9 ms·
Unfortunately the new tricks can't be used when the codebase is still stuck on .net framework :(
by belinder 6y ago
Unfortunately the new tricks can't be used when the codebase is still stuck on .net framework :(
- lwansbrough 6y agoAllegedly there's an upgrade path from .NET 4.8 to .NET 5.
- keithnz 6y agoif you have built anything on web forms, then you really have no way forward other than rewriting all that. That alone will keep many an enterprise locked on .NET Framework for quite some time.
- belinder 6y agoIn our case not web forms but WCF
- WorldMaker 6y agoYou may want to keep an eye on CoreWCF: https://github.com/CoreWCF/CoreWCF https://github.com/CoreWCF/CoreWCF 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.
- UweSchmidt 6y agoCould you expand a little on that? How exactly does an REST API backed desktop/forms application look like in 2021, and how is the decoupling accomplished?
- WorldMaker 6y agoA lot of the decoupling is naturally accomplished by just not being backward compatible with previous WCF bindings and throwing out the whole mess. 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.
- Analemma_ 6y agoI second the other commenter suggesting you should try to rip off the WCF bandaid and go to a RESTful API as soon as you can. It sounds scary but after the one-time pain of migration we've had way fewer "magic, black box" errors that require insane investigations and hacks.
- starik36 6y agoThere is a tool out there that converts WCF to gRPC. https://visualrecode.com/ https://visualrecode.com/ The guy who wrote it talking about it: https://www.dotnetrocks.com/?show=1728 https://www.dotnetrocks.com/?show=1728
- starik36 6y agoYou can give it a shot with this project. https://github.com/FritzAndFriends/BlazorWebFormsComponents https://github.com/FritzAndFriends/BlazorWebFormsComponents It emulates WebForms component with Blazor. Although I would just start from scratch.
- goto11 6y ago> Although I would just start from scratch. Which is fine if you are a hobbyist developing for fun.
- aliswe 6y agoNot really
- goto11 6y agoThe upgrade path is massive rewrites, something most business are wary of. For good reasons. 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.
- nycdotnet 6y agoAt work we've been slowly pulling code out of our WebForms monolith. That's still on .NET Framework, and will be forever until we're done killing it, but we can use recent VS and MSBuild with it and we use C# 9 as well. Business code generally works copy and paste in .NET Core, so there's a really good path to migrate to newer stuff, especially with .Net Standard 2.0 being a thing. 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.
- nikanj 6y agoYour programming language either dies young, or it lives long enough to become the very legacy crud it sought to replace.
- wvenable 6y ago> MS really made a grave mistake by coupling the evolution of the C# language to the .NET version. 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.
- Mindless2112 6y agoYou can (and I do), but it is explicitly not supported. If it breaks, you get to keep both halves.
- nullsense 6y ago
- nullsense 6y agoAllegedly there's also a route to the top of Mt Everest. For some of us the "upgrade path" is impassable.
- shireboy 6y agoThere are ways, but definitely can be hard to get unstuck from framework. This came across my newsfeed this am: https://www.telerik.com/blogs/jump-starting-migration-dotnet-core-with-upgrade-assistant https://www.telerik.com/blogs/jump-starting-migration-dotnet... and also, the other day, dotnet rocks podcast had a guy on talking about an upgrade tool. I think it was this one: https://visualrecode.com/ https://visualrecode.com/ He was also discussing the "Strangler Pattern": https://akfpartners.com/growth-blog/strangler-pattern-dos-and-donts https://akfpartners.com/growth-blog/strangler-pattern-dos-an...
- WorldMaker 6y agoNot by default, no. These two specific tricks should work on .NET Framework (some of the other tricks in C# after 7 or 8 require functionality that .NET Framework doesn't have, though). You can ask VS to use the more recent C# compiler with the LangVersion tag in the .csproj: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/configure-language-version https://docs.microsoft.com/en-us/dotnet/csharp/language-refe... Obviously, it's not suggested doing that nor is entirely well supported, but it is at least allowed. Though if you are looking to use top-level programs you probably are working in greenfields anyway that should just be .NET 5+. It's not really a feature that makes a lot of sense for existing codebases as it is more a teaching tool/"quick and dirty command line app/script" tool.
- nycdotnet 6y agoWe use C# 9 in our WebForms monolith and it works fine. Just add `<LangVersion>latest</LangVersion>` to your .csproj file. (This assumes you're using recent Visual Studio version and use a recent version of MSBuild as well)
- linknoid 6y agoThere are a few language features which require a specific type to be defined, but you can define those types yourself. For example, to use record syntax, you need to define this attribute: namespace System.Runtime.CompilerServices { public class IsExternalInit : Attribute { } } And supporting the new indexing syntax requires you to define System.Index and System.Range types, which are a bit more involved, but still pretty trivial: https://docs.microsoft.com/en-us/dotnet/api/system.index?view=net-5.0 https://docs.microsoft.com/en-us/dotnet/api/system.index?vie... https://docs.microsoft.com/en-us/dotnet/api/system.range?view=net-5.0 https://docs.microsoft.com/en-us/dotnet/api/system.range?vie... But pretty much all the other new C# language features I've tried have just worked straight out of the box with .NET 4.7.2.
- bob1029 6y agoThere are many paths out of hell. Check out the windows compatibility pack for all things active directory, WCF & System.Drawing: https://docs.microsoft.com/en-us/dotnet/core/porting/windows-compat-pack https://docs.microsoft.com/en-us/dotnet/core/porting/windows... Winforms is probably a no-go on migration, but you should definitely check out Blazor if you want to develop any new business apps. We have constructed some incredibly complex business dashboards using this framework and cant imagine how some of this would even be possible if we had to move back to a front-end client framework and invent a bunch of JSON APIs. Also, the new Blazor Desktop stuff is extremely exciting: https://medium.com/young-coder/blazor-desktop-the-electron-for-net-ecdcf5c30027 https://medium.com/young-coder/blazor-desktop-the-electron-f... > The first difference is that the WebWindow container doesn’t use WebAssembly at all. Yes, you can run more or less the same Blazor application in WebWindow as you would in a web page. But when you use a web page, it’s executed by a lightweight .NET runtime that’s powered by WebAssembly. When you use it in WebWindow, it will use the cross-platform .NET runtime directly. There is a lot of really amazing stuff coming down the roadmap, so I can easily advocate for enduring some degree of pain to get on this wagon.
- thrower123 6y agoI'm pretty sure WinForms is being migrated. I've built dotnet 5 WinForms apps, anyway. At least on Windows - I wouldn't bet on a Linux Gtk/Qt port any time soon. WPF is probably dead though.
- my123 6y agoWPF is not dead, it got open-sourced and was ported to .NET Core 3.1 onwards.
- ziml77 6y agoMicrosoft wouldn't let WPF die. Anyone writing enterprise desktop applications is using it heavily.
- tonyedgecombe 6y agoAnyone writing enterprise desktop applications is using it heavily. I don't think there is much of that going on anymore. In reality Microsoft did let WPF languish for years, it always felt unfinished. I was very surprised when they migrated it to .Net core.