At NDC Olso I was part of a panel discussion with Julie Lerman, David Fowl er, Damian Edwards, and Bryan Hogan. Here are my stream of consciousness answers for some of the questions presented to the panelists. Not all the questions were directed to me, but I jotted down some thoughts nonetheless.
This might sound odd, but I’m excited about WPF and Windows Forms. It’s not that I want to go out and write a new application using WinForms. But, I have a WinForms application that is still in production and is old enough to graduate from high school. I feel good knowing that Microsoft recognizes the importance of these older frameworks and the importance of writing desktop applications. For some scenarios, desktop applications are easier to build than web applications, and for the first time in more than 5 years I feel like .NET supports the desktop.
I’m also excited about gRPC services in ASP.NET Core. I think the enterprise struggles with the alternatives to WCF and SOAP. REST and hypermedia work well for some services and applications, but there are many scenarios where you need to bang out a distributed service and don’t need the overhead of perfectly decoupled components. In other words, HTTP and JSON are great, but the old days of “Add Service Reference” aren’t as bad as many people make them out to be. Like it or not, SOAP and WS-* protocols still perform significant amounts of work in today’s world. I believe gPRC can be a better SOAP.
My favorite new API is Math.FusedMultiplyAdd. The operation sounds like something you might need in the software for a thermonuclear simulator. It’s fast, and it’s accurate! Be careful!
I think EF needs to expand its reach far beyond relational databases. I know EF Core 3 is going to support CosmosDB, but its taking a long time to get there, and I already have good abstractions I can use in the Cosmos DB SDK, so I don’t need EF there.
It’s funny, ten years ago I considered relational databases to be the only way to store data. Then I started using MongoDB in real applications and I started to see all the alternatives. Today, I think of relational databases as specialized high-end storage for specific use cases. The bulk of my data, in terms of both volume and processing, lives outside of a SQL database. The data is in blob storage, and in data lakes, and is streaming through event grids, and getting crunched in Apache Spark clusters. That’s where I need help with data.
I think the best thing EF could do moving forward is to split into two frameworks. One part of the framework could map data from CSV files and JSON payloads into CLR objects as quickly as possible. But, I don’t want just an object mapper in the AutoMapper sense, I also want something similar to an F# type provider for C#. I want to point to data in an Azure data lake or an event grid stream and then express my computations using strong types.
The other part of the framework could focus on sending commands and queries to a remote data source for processing. Currently, EF translates LINQ expressions into SQL, but I think we need to give up on the dream of LINQ to everything. It takes too long for EF to support new databases, like ComosDB. It takes EF too long to support common features of a single database, like views and stored procedures in SQL. What we need is an EF that allows developers to use native data processing languages in straightforward fashion. Give me an elegant way to embed SQL statements in my code. SQL is everywhere! SQL is a language supported by SQL Server, by Cosmos DB, by Apache Spark, and in the future even blob storage in Azure. I need to take advantage of as many SQL features as I can without being limited by what can be expressed in C#, and then I need to execute the SQL and map results into objects.
In short, I want better language interop and forget about abstracting heterogeneous data sources behind C# expressions.
I do worry. I’m worried about people getting left behind, and I’m worrying about people getting confused and giving up. A couple of years ago I made a deliberate move away from front-end development because I felt the pace of change was unhealthy. It felt like everything was changing, but not getting better. The improvements were small and not worth the cost of keeping up to date. I always use webpack 4 as a specific example. There were many breaking changes between version 4 and version 3. For example, loaders were removed and replaced by rules. From what I could tell, rules don’t offer any features beyond loaders, but everyone moving from webpack 3 to webpack 4 starts with a broken webpack build because of the change, and they need to research the change and find out how to update their webpack configuration.
I think .NET and the C# language are both changing, and I do believe they are moving forward, they are improving, and they are not just changing to make a change. But, I do worry that Microsoft doesn’t keep backward compatibility as a priority anymore. I know that backward compatibility can be an albatross and there’s been a lot of bad decisions made in the name of backward compatibility, but I also know I’m not pushing my team to update their ASP.NET Core 1.1 applications because of all the breaking changes in moving to 2.2. We’ll need to move eventually, but there’s nothing forcing us to move today except for the end of support coming in a few weeks. We’ll have to set aside a couple days to make the move and figure out the new package names, the new extension method namespaces, the new name for the web host builder, and how to configure the new authentication and authorization services and middleware. Then we have to run some tests and make sure we have no regressions in performance, features, or security. Upgrading is not just setting a version property in a project file, sometimes you need to learn about the philosophy changes in the framework.
Yes, I do. Just last month I was working with a development team that made it clear from the start that this team uses a DBA, and the DBA is going to be solely responsible for writing all SQL queries for the database.
It is a reasonable decision to avoid the Entity Framework, and there are many reasons you can use to justify this decision. I only ask teams to avoid EF for the right reasons. Don’t avoid EF because you think EF is insecure. I’d bet EF does a better job avoiding SQL injection attacks than hand rolled code. Don’t avoid EF because you think EF will be slow, there are many scenarios where EF is fast enough.
If .NET includes the C# language, too, the first thing I’d rip out and redo is async and await. We need async programming models, but the current solution is fragile and frustrating. I don't like the Async postfix convention in my codebase. I don’t want to see ConfigureAwait in my library code. I don’t want to worry about running sync code over async code or async code over sync code. We need better operability because here we don’t always have perfectly async code bases and libraries.
What I’m saying is – I want to call Task.Result and not feel dirty or fearful.
For anyone who hasn’t heard of Ballerina, go visit ballerina.io. I worry about baking Ballerina type features into the language because I’m afraid we’ll end up with something like async and await where the solution covers 80% of the easy scenarios, but the last 20% is painful or near impossible.
Like it or not, C# is a general purpose programming language, so you are going to have scenarios that require boilerplate code. I do think we can make some changes to the language that can help eliminate boilerplate code. Every time I look at a project that generates Swagger docs or OpenAPI docs, there are these
[Produces] attributes all over the code. The attributes are noisy and I always wonder why the tools can't figure out the real return type.
Or, better yet, why can’t the language express what I’m going to return? C# is an object oriented language so I need to write methods with a return type like
IActionResult to cover all possible return types. But,
IActionResult loses all the fidelity you can have with the concrete types the method actually uses. What if C# had the F# concept of a sum type, or discriminated union? Then I don’t have to lose type fidelity by specifying a return type with some base class or interface. I think changes like this would make C# and then .NET appeal to an even broader audience.
I also think .NET and the tools can continue to improve for the new world of microservices. Look at what’s happened with HttpClient over the years. The original version was impossible to use correctly, because you had to choose between network socket starvation on one hand, and infinite DNS cache lookups on the other. So, we need smarter bits of infrastructure, and we need better scaffolding tools. The scaffolding tools with MVC 5 are light years ahead of the tools in ASP.NET Core in terms of features and performance.
Thanks for reading, and thanks to every who came to see the panel live!