DEV Community

Erikvdv
Erikvdv

Posted on

Creating a realworld app with C# dotnet

Once in a while I create a realworld app (demo) to learn a new framework or explore certain different ways of application architecture.

After experimenting with several frameworks to implement the frontend, this time I decided to create the backend. I used C# .Net for this.

My code can be found here

Recent years I have been using this stack extensively and this time, next to experimenting a bit, I aimed to create a clean reference that I would be able to refer to when creating future solutions.

The key things I like about implementing a real world app are reading about best practices and implement them in an elegant way and experimenting with some concepts/libraries that might help with that.

The solution

For the solution I opted for a fairly traditional clean architecture setup using .Net 6.
The solution consists of the following layers:

  • api (wires up the solution and defines the api endpoints)
  • core (contains the core business logic)
  • data (contains the interaction with the DB)
  • infrastructure (generic code that potentially could be used in different solutions)

And I used the following features:

  • the new WebApplication.CreateBuilder(args)
  • file scoped namespaces
  • global usings
  • Entity Framework Core with SQLite db
  • serilog for logging, integrated with application insights, including realtime monitoring
  • Hellang.Middleware.ProblemDetails for consistent error output
  • sonarlint for code scanning

Justification of choices and Retrospective

Within the remainder of this post I will reflect on the choices I made.

Application layering

  • using distinct projects for this specific implementation is not required within this application. However, it makes it more clear where specific responsibilities should be.

  • Api Layer: I have considered using the .Net 6 minimal api's. However, I do think at this moment it is a bit too early as they are still lacking features (e.g. api grouping, model validation). I could have used something like Carter, but it relies on FluentValidation, which I always find hard to debug. I prefer something like this that is easy to debug and understand.

  • I have doubted if I should combine the Core and Data layer into a single layer. As I am using Entity Framework in the data layer, the core layer (or at least the developer) actually needs to be aware of the EF concepts. The benefit of the current split is that it is easier to validate the database interaction (as can be seen here) and that the services in the core layer are easier to unit test as the repository can easily be mocked)

Features

  • I do like the the WebApplication.CreateBuilder(args) that is new in .Net 6. It is easier to just have a program.cs file where both the host, the services and request pipeline is configured, instead of having a separate Startup file as well. For bigger projects I do expect one would like to structure the program.cs file a bit more as it could become hard to navigate

  • file scoped namespaces: even being small, in my view this is a huge improvement that came with .Net 6 in terms of readability. Personally I would even like to have the option to go "namespaceless" by just taking the folder structure and a rootnamespace defined in the csproj file as the namespace.

  • global usings: Don't see a lot of benefits here, while developing I manually needed to move stuff that is normally just handled by my IDE.

  • serilog: I do like serilog for logging, however the integration with Application Insights is limited to log events as events or as traces, which prevents requests to be logged as requests in AI.

  • Hellang.Middleware.ProblemDetails really works well for me. It makes it very easy to add a global exception handler that allows for consistent responses for all types of problems, whether they are technical or functional and works well with the .Net default ApiController problem details response for model validation.

  • sonarlint for code scanning: I do think this is beneficial mainly to keep a consistent code style in your project (together with the other config in .editorconfig)

Conclusion

I can recommend anyone to build a realworld app. It really encourages you to dive deeper in a language/framework than what you would to in your typical todo app tutorial.
If you are more familiar with a language/framework it allows you to experiment with architectures you are less familiar with.
Besides that, when you like solving puzzles like me, your time is definitely more valuable spend than on solving Sudoku's ;).

Looking specifically at this C# .Net implementation it might help you to think about how to practically structure your application

Top comments (2)

Collapse
 
eljayadobe profile image
Eljay-Adobe

I find the .NET platform to be excellent. The tooling (especially refactoring), languages, IDEs, and expressivity are all top-notch. I've done three very large projects using C# and .NET.

I've also futzed around with F#, following the excellent tutorial The Book of F# by Dave Fancher, and I am enamored with F#. (F# is basically OCaml for .NET.) I love learning new programming languages, and F# also taught me a new programming paradigm. (I could have learned that paradigm from Haskell, or OCaml, or Elm, but I learned it from F# first.)

I did all my F# futzing around using Visual Studio for Mac (Community Edition).

I also have the same good things to say about the JVM platform. I did three very large projects using Java on the JVM platform.

Collapse
 
ayodejii profile image
Isaac Ayodeji Ikusika

Nice.
i'm glad dotnet is getting more users in.