loading...
Cover image for Episode 001 - The Reference Project - ASP.NET Core: From 0 to overkill

Episode 001 - The Reference Project - ASP.NET Core: From 0 to overkill

joaofbantunes profile image João Antunes Originally published at blog.codingmilitia.com on ・3 min read

ASP.NET Core: From 0 to overkill (45 Part Series)

1) ASP.NET Core: From 0 to overkill - Intro 2) Episode 001 - The Reference Project - ASP.NET Core: From 0 to overkill 3 ... 43 3) Episode 002 - Project structure plus first application - ASP.NET Core: From 0 to overkill 4) Episode 003 - First steps with MVC - ASP.NET Core: From 0 to overkill 5) Episode 004 - The Program and Startup classes - ASP.NET Core: From 0 to overkill 6) Episode 005 - Dependency Injection - ASP.NET Core: From 0 to overkill 7) Episode 006 - Configuration - ASP.NET Core: From 0 to overkill 8) Episode 007 - Logging - ASP.NET Core: From 0 to overkill 9) Episode 008 - Middlewares - ASP.NET Core: From 0 to overkill 10) Episode 009 - MVC filters - ASP.NET Core: From 0 to overkill 11) Episode 010 - Async all the things - ASP.NET Core: From 0 to overkill 12) Episode 011 - Data access with Entity Framework Core - ASP.NET Core: From 0 to overkill 13) Episode 012 - Move to a Web API - ASP.NET Core: From 0 to overkill 14) Episode 013 - Starting the frontend with Vue.js - ASP.NET Core: From 0 to overkill 15) Episode 014 - Centralizing frontend state with Vuex - ASP.NET Core: From 0 to overkill 16) Episode 015 - Calling the Web API from the frontend - ASP.NET Core: From 0 to overkill 17) Episode 016 - Authentication with Identity and Razor Pages - ASP.NET Core: From 0 to overkill 18) Episode 017 - More Identity, more Razor Pages - ASP.NET Core: From 0 to overkill 19) Episode 018 - Internationalization - ASP.NET Core: From 0 to overkill 20) Episode 019 - Roles, claims and policies - ASP.NET Core: From 0 to overkill 21) Episode 020 - The backend for frontend and the HttpClient - ASP.NET Core: From 0 to overkill 22) Episode 021 - Integrating IdentityServer4 - Part 1 - Overview - ASP.NET Core: From 0 to overkill 23) Episode 022 - Integrating IdentityServer4 - Part 2 - Auth Service - ASP.NET Core: From 0 to overkill 24) Episode 023 - Integrating IdentityServer4 - Part 3 - API - ASP.NET Core: From 0 to overkill 25) Episode 024 - Integrating IdentityServer4 - Part 4 - Back for Front - ASP.NET Core: From 0 to overkill 26) Episode 025 - Integrating IdentityServer4 - Part 5 - Frontend - ASP.NET Core: From 0 to overkill 27) Episode 026 - Getting started with Docker - ASP.NET Core: From 0 to overkill 28) Episode 027 - Up and running with Docker Compose - ASP.NET Core: From 0 to overkill 29) Episode 028 - Multiple service instances tweaks - ASP.NET Core: From 0 to overkill 30) Episode 029 - Simplifying the BFF with ProxyKit - ASP.NET Core: From 0 to overkill 31) Episode 030 - Analyzing performance with BenchmarkDotNet - ASP.NET Core: From 0 to overkill 32) Episode 031 - Some simple unit tests with xUnit - ASP.NET Core: From 0 to overkill 33) Episode 032 - Upgrading to ASP.NET Core 3.0 - ASP.NET Core: From 0 to overkill 34) E033 - Redesigning the API: Improving the internal architecture - ASPF02O 35) E034 - Segregating use cases with MediatR - ASPF02O 36) E035 - Experimenting with (yet) another approach to data access organization - ASPF02O 37) E036 - Making things more object oriented with rich domain entities - ASPF02O 38) Better use of types - avoiding nulls with an Optional type - ASPF02O|E037 39) More explicit domain error handling and fewer exceptions with Either and Error types [ASPF02O|E038] 40) Event-driven integration - Overview [ASPF02O|E039] 41) Event-driven integration #1 - Intro to the transactional outbox pattern [ASPF02O|E040] 42) Event-driven integration #2 - Inferring events from EF Core changes [ASPF02O|E041] 43) Event-driven integration #3 - Storing events in the outbox table [ASPF02O|E042] 44) Event-driven integration #4 - Outbox publisher (feat. IHostedService & Channels) [ASPF02O|E043] 45) Event-driven integration #5 - Quick intro to Apache Kafka [ASPF02O|E044]

I had already prepared the first episode starting to code the project when I realized, maybe it’s a better idea to start with explaining what’s the goal “product” wise, for everyone to have the context before starting coding like a maniac on something no one would understand.

Given this, the following video provides an overview, but if you prefer a quick read, skip to the written synthesis.

The playlist for the whole series is here.

Concepts

Like I mentioned previously, the goal of the project is to make a friendly sports event managing application, to be used by those who gather some friends to play something with their friends. The initial idea was centered around football (or soccer) but I’ll try to make it generic.

With this in mind, trying to find the main concepts that fit this idea I came up with:

  • Users - well… this one is unexpected right? 😆
  • Groups - groups of friends that gather to play
  • Players - players are a different concept than a user to allow for groups of people where not everyone wants to use the application, but the users who want to can still manage everything even if there’s someone who’s not a registered user
  • Match/event/game - represents the specific event that has/is/will happen
  • Teams - the teams that play the match - this may very well be something fixed, but also something scoped to a match, where the teams are defined each time
  • Statistics - something interesting is to keep statistics os the various matches, like match scores, goal/point/other scorers, fouls, etc

Desired features

While writing down the concepts, the desired features started to come to mind (along with some components that’ll be written down in the next section):

  • Create/manage users
    • Define email, name, nickname, profile picture, …
  • Communication
    • Send emails, notifications, …
    • Manage preferences
  • Create/manage groups
    • Invite users
    • Create players
    • Associate players with users
    • Set a specific sport for the group
  • Matches
    • Schedule
    • Manage information
    • When, where, players involved, teams chosen, …
    • Add events
    • Goal scored, foul suffered, … (more and sport dependent)
    • Live
    • Be able to add match events during the match and be able to see the stats evolve realtime

Components

Ok, with the concepts and desired features laid out as best as possible for this kind of project (if a business analyst gave something like this to one of us, we would probably be enraged 😝) we can start to picture our over-engineered system, where we try to fit in every possible hipster technology… and as this is that kind of project, that’ll be exactly what’ll happen!

The following is something of the sort of a very high level architecture. It’ll most certainly change along the way (for the best hopefully) but I think can summarize the initial ideas.

High level architecture

We can see basically an organization of the various components, where even if we’re over-engineering the solution, we don’t want the components to be like CRUD services, but be as much as possible self contained services that can implement a specific feature set.

With this in mind we have:

  • Users - to handle registration, authentication and other user management requirements
  • GroupManagement - to handle everything group related, from associating users to managing players.
  • Communication - to handle all communication requirements, including the user’s communication preferences.
  • Matches - to handle everything match specific, like when and where, scores, match events and more, except the live part.
  • LiveMatches - will probably be separated from the main matches component as it’ll have the realtime requirement and maybe useful to be isolated.
  • Statistics - this will be a central place to handle all statistics, even if they originally come from the match events - we’ll see in the long run how (and if we should) orchestrate this service with the matches one.

Besides this components responsible for the application logic, we’ll need a frontend to see it all working. To feed the frontend I’m thinking of going with a “backend for frontend”, to provide everything in the best way possible for the web frontend. The mobile part is out of scope, just added to the image as a possibility.

Outro

Not being a specification (not even close), I think this post can give a good initial idea of what’s the desired end result. If not, let me know so I can improve it.

Thanks for stopping by, cyaz!

ASP.NET Core: From 0 to overkill (45 Part Series)

1) ASP.NET Core: From 0 to overkill - Intro 2) Episode 001 - The Reference Project - ASP.NET Core: From 0 to overkill 3 ... 43 3) Episode 002 - Project structure plus first application - ASP.NET Core: From 0 to overkill 4) Episode 003 - First steps with MVC - ASP.NET Core: From 0 to overkill 5) Episode 004 - The Program and Startup classes - ASP.NET Core: From 0 to overkill 6) Episode 005 - Dependency Injection - ASP.NET Core: From 0 to overkill 7) Episode 006 - Configuration - ASP.NET Core: From 0 to overkill 8) Episode 007 - Logging - ASP.NET Core: From 0 to overkill 9) Episode 008 - Middlewares - ASP.NET Core: From 0 to overkill 10) Episode 009 - MVC filters - ASP.NET Core: From 0 to overkill 11) Episode 010 - Async all the things - ASP.NET Core: From 0 to overkill 12) Episode 011 - Data access with Entity Framework Core - ASP.NET Core: From 0 to overkill 13) Episode 012 - Move to a Web API - ASP.NET Core: From 0 to overkill 14) Episode 013 - Starting the frontend with Vue.js - ASP.NET Core: From 0 to overkill 15) Episode 014 - Centralizing frontend state with Vuex - ASP.NET Core: From 0 to overkill 16) Episode 015 - Calling the Web API from the frontend - ASP.NET Core: From 0 to overkill 17) Episode 016 - Authentication with Identity and Razor Pages - ASP.NET Core: From 0 to overkill 18) Episode 017 - More Identity, more Razor Pages - ASP.NET Core: From 0 to overkill 19) Episode 018 - Internationalization - ASP.NET Core: From 0 to overkill 20) Episode 019 - Roles, claims and policies - ASP.NET Core: From 0 to overkill 21) Episode 020 - The backend for frontend and the HttpClient - ASP.NET Core: From 0 to overkill 22) Episode 021 - Integrating IdentityServer4 - Part 1 - Overview - ASP.NET Core: From 0 to overkill 23) Episode 022 - Integrating IdentityServer4 - Part 2 - Auth Service - ASP.NET Core: From 0 to overkill 24) Episode 023 - Integrating IdentityServer4 - Part 3 - API - ASP.NET Core: From 0 to overkill 25) Episode 024 - Integrating IdentityServer4 - Part 4 - Back for Front - ASP.NET Core: From 0 to overkill 26) Episode 025 - Integrating IdentityServer4 - Part 5 - Frontend - ASP.NET Core: From 0 to overkill 27) Episode 026 - Getting started with Docker - ASP.NET Core: From 0 to overkill 28) Episode 027 - Up and running with Docker Compose - ASP.NET Core: From 0 to overkill 29) Episode 028 - Multiple service instances tweaks - ASP.NET Core: From 0 to overkill 30) Episode 029 - Simplifying the BFF with ProxyKit - ASP.NET Core: From 0 to overkill 31) Episode 030 - Analyzing performance with BenchmarkDotNet - ASP.NET Core: From 0 to overkill 32) Episode 031 - Some simple unit tests with xUnit - ASP.NET Core: From 0 to overkill 33) Episode 032 - Upgrading to ASP.NET Core 3.0 - ASP.NET Core: From 0 to overkill 34) E033 - Redesigning the API: Improving the internal architecture - ASPF02O 35) E034 - Segregating use cases with MediatR - ASPF02O 36) E035 - Experimenting with (yet) another approach to data access organization - ASPF02O 37) E036 - Making things more object oriented with rich domain entities - ASPF02O 38) Better use of types - avoiding nulls with an Optional type - ASPF02O|E037 39) More explicit domain error handling and fewer exceptions with Either and Error types [ASPF02O|E038] 40) Event-driven integration - Overview [ASPF02O|E039] 41) Event-driven integration #1 - Intro to the transactional outbox pattern [ASPF02O|E040] 42) Event-driven integration #2 - Inferring events from EF Core changes [ASPF02O|E041] 43) Event-driven integration #3 - Storing events in the outbox table [ASPF02O|E042] 44) Event-driven integration #4 - Outbox publisher (feat. IHostedService & Channels) [ASPF02O|E043] 45) Event-driven integration #5 - Quick intro to Apache Kafka [ASPF02O|E044]

Posted on Dec 6 '18 by:

Discussion

markdown guide
 

Thank you for sharing this beautiful insights with me. Reading this part of your article makes me fekt like I was in a board room meeting where the CTO asked me to come up with this project. I love the idea of the boxes above it kind of makes me see a clearer path into the project.

 

Glad it's helpful!
It's far from perfect and very high level look, plus things are certainly bound to change, but hopefully it's good enough to understand the base idea.

 

I haven't used ASP.Net since ASP.Net MVC 1 came out I know I can RTFM but maybe you can answer some quick questions for me.

  1. What important things do I lose by using Core vs regular .net?
  2. What's the performance story like in recent ASP.Net MVC releases? Much faster than rails? Par with Go? Slower than Go? About the same as Elixir?
 

Sure, no problem.

Regarding question 1:

I don't feel you lose anything, if anything, it's the other way around, but there are somethings to take into account.

As .NET Core is not shipped with Windows like the .NET Framework, they can iterate on it faster. That's more inline with other technologies that release new versions more regularly, but has the same issue as others in that regard - support lasts for less time than the full framework which is supported as long as the Windows version is (i.e. a long long time!). If I'm not mistaken .NET Core is supported for 3 years on LTS versions, and some months for the others.

When .NET Core 1.0 was released, there were a lot of missing APIs that existed in .NET Framework, but with the release of 2.0 (and .NET Standard 2.0, which is like a contract that states what APIs a compatible .NET runtime must provide) they were mostly put up to par, except for Windows specific things - for this scenario they added the Windows Compatibility Pack.

And of course, being cross platform makes it better than ever, as if you prefer to run it on Linux servers, you can (and use Docker and those things that we couldn't with the .NET Framework).

And as a side note, we can (or at least could when on version 1.0) run ASP.NET Core on .NET Framework. It's probably not the ideal, but could be a good migration path for those who need it, not needing to completely jump the base framework plus web framework). Also a plus if one has dependencies on older libraries.

Regarding question 2:

Performance has improved a lot. Not only are they more focused on it than before, but being open source, people with specific needs just went ahead and improved things that were critical for them.

For real numbers you can check out the TechEmpower benchmarks which compares a lot of web frameworks. In some test scenarios ASP.NET Core is up on the top, in others not so much, but the effort to make it better is clearly there.

In the latest releases they created some new APIs to facilitate development of lower level stuff (like Span and Memory used in networking code) and even added C# features, also for lower level stuff (readonly structs).

Hope this was helpful 👍

 

amazing , that what we miss in real life project .