Development Central

Bill Sorensen's software development blog

The future of ASP.NET Core

The new ASP.NET Core 2.0 packages can no longer be used on .NET Desktop

This issue on the aspnet GitHub site has caused some controversy. So what's the deal?

ASP.NET Core 2.0 (which is not yet released) is currently targeting only .NET Core. Unless this changes, it means that the new version will not support the .NET Framework.

Some background (because the names are really confusing):

.NET Core is a cross-platform version of .NET. It is not currently feature-complete compared to .NET Framework.

.NET Framework is the Windows-based .NET we're used to. It supports everything but the kitchen sink.

ASP.NET Core is (more or less) ASP.NET MVC 6 + ASP.NET Web API with OWIN support. The latter is particularly nice for integration testing. Despite the "Core" name, it can (could) target .NET Framework or .NET Core.

This is simplified and not exact, but it's close enough IMHO.

Right now you can create a web site using the current version of ASP.NET Core (1.1) and target .NET Framework 4.x, reference existing assemblies, and deploy to IIS.

According to .NET Core Support Policy (which also covers ASP.NET Core per the FAQ), 1.1 support could end 12 months after the 2.0 release (if I'm reading this right). 2.0 may be out this month. The implication is that 1.1 support may end mid-2018 (see Scott Hanselman's comment).

So let's say you're an enterprise developer, and you need to replace a legacy ASP.NET Web Forms site. The site uses a lot of in-house and third-party DLLs, integrating with SOAP services and COTS software. What technology do you use?

A week ago I recommended ASP.NET Core 1.1 targeting the .NET Framework for just this scenario. Now I'm finding that was an unwise decision. In a year, we could end up with a site built on an unsupported technology, with potentially no migration path. All it takes is one feature that .NET Core doesn't support.

Currently, better options include ASP.NET MVC 5 and the excellent Nancy framework (which does support OWIN).

I believe this will hurt adoption of ASP.NET Core, particularly in the enterprise. My hope is that the team will reconsider, as none of this is final.

[Update: Support for ASP.NET Core 1.1 on .NET Framework will be extended until July 2019 at least. See Damian Edwards' comment.]

Notes: Pragmatic Architecture in .NET

Notes on a talk by Cory House (@housecor) at Iowa Code Camp.

Clean Code video on Pluralsight.

Religion is the problem in architecture. Always/never.
Look at the context.
It depends.
People who are experts answer questions with more questions.

Over-architecting wastes money.


What if one month late is worthless?

Parkinson's Law: Work expands to fill available time.

Consider Complexity (speaker considers the following complex)

  • Automated testing
  • Coding to an interface
  • SOA
  • Rich Domain Model (DDD)
  • ORM vs. custom DAL
  • Repository Pattern
  • Layered architecture

Consider Simplicity

  • Do the simplest thing that could possibly work
  • Lean/Agile principles (minimize WIP, etc.)
  • 80/20 Rule

Book: Lean Startup - minimal viable product (MVP)
Scalability, maintenance costs, performance, etc. may not matter

We're paid for solutions, not code.

Flexing features (scope) is a lot better way to go than flexing quality.

Is it worth taking on technical debt today?
Hard vs. Soft deadlines

  • Trade show?
  • First to market?

Single loud customer, salesman misspoke, wild-ass guess, MS Project said so - terrible reasons for hard deadline

Layers - logical (separation of concerns)
Tiers - physical (often decided for you)

For a small enough application, methods are layers.

Everything's a trade-off.

Architectural Levels

  1. Simplest thing
  2. Somewhere in between
  3. Every tool in the shed

Active Record pattern mixes Domain and Data. Breaks SRP.
Easy to understand, though. Consider for CRUD apps or simple domain.
Rigid: Domain model = DB
Leads to God object
Hard to test
Converting to Repository Pattern = pain

Eric Evans - DDD book
Great for complicated, long-lived applications
Takes time

Level 2 (somewhere in between)
Focus on the pain

No Free Lunch

At what point does our application complexity grow to the point where the effort to enhance gets too painful?

MVP, junior team, simple domain, tight timeline, throwaway - consider Level 1

Flagship product, senior team, complex domain, long-term, security matters, flexible timeline - consider Level 3

POEAA (Fowler) and Dino Esposito's architecture book inspired this talk.
Microsoft .NET: Architecting Applications for the Enterprise is the latter.

Speaker recommends clean, readable code regardless.

That's not TDD

I'm currently reading Pro ASP.NET MVC 4 as part of learning web development. So far it's been a good tutorial, but I take issue with the author's coverage of Test-Driven Development (TDD).

I applaud the coverage of unit testing, dependency injection, mocking, separation of concerns, and other best practices. It's the details that bother me.

In chapter 6, the author says he will follow the TDD approach in a unit test example. He starts out by writing the system under test and having it throw a NotImplementedException. Bzzt. Write the test first. There is a reason for this: the tests guide your design. You write the API you want to consume.

Next, he writes the unit tests. All of them. In TDD, you write one test, see it fail, write code to get it to pass, refactor, and then repeat. While there's no law that unit tests must be written in that fashion, changing the process means you're not doing TDD. If you don't want to do TDD, fine, but don't call it that.

Several of the tests violate the guideline of one logical assert per test. The only justification I can see is brevity. This comes at a cost: when the first assert fails, subsequent asserts are not run. In addition, messages have to be added to the asserts for clarity; it's much better to include this information in the test method name.

// These should be three separate test methods
Assert.AreEqual(5, TenDollarDiscount, "$10 discount is wrong");
Assert.AreEqual(95, HundredDollarDiscount, "$100 discount is wrong");
Assert.AreEqual(45, FiftyDollarDiscount, "$50 discount is wrong");

The author encourages use of the ExpectedExceptionAttribute. This is far too coarse-grained, and is one reason for avoiding MSTest (which the book also promotes).

I encourage everyone to go to the experts to learn TDD and unit testing. Two good sources are Test Driven Development: By Example and The Art of Unit Testing.

The book's coverage of dependency injection is incomplete as well; the authoritative work is Dependency Injection in .NET.

I'm being harsh for a book on ASP.NET MVC. If you're going to cover these topics in detail, though, please get the details right.


A coworker and I spent a total of at least 8 man-hours this week tracing down one threading bug. The original author was locking access to shared state, and got it almost right.

Writing thread-safe code that uses global mutable state is hard. It's much easier to avoid the problem entirely.

Functional programming emphasizes pure functions (the same inputs will always give the same output, with no side effects) and immutable types. If you write your code in that style, thread safety comes naturally.

Regardless of programming language, consider a more functional approach. Your future self will thank me.

For a good book on the subject, try Real-World Functional Programming: With Examples in F# and C#.

Speaking at CRineta

I'm giving a presentation on FSM.NET at the local users' group on Monday night. @dahlbyk is opening for me, so I've got a tough act to follow.

Meeting info


My first open source project on GitHub is FSM.NET, a simple "stateless" finite-state machine library for .NET. It's also available through NuGet.

The library is written in F#, but is designed to be easily callable from C#. The project includes examples in both languages.