Posts
To add global exception handling in ASP.NET Core just use configuration method:
app.UseExceptionHandler
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-6.0#exception-handler-lambda
What ASP.NET Middleware can do?
Pretty much everything. Default ASP.NET Core request handling pipeline is consisting of bunch of middlewares:
Authentication Authorization CORS HTTP Logging MVC Static Files other Whole list of built-in middlewares can be found here:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-7.0#built-in-middleware There is possibility to write custom middleware too.
Middleware in OWIN
There are 2 ways of writing OWIN middleware in ASP.NET Core.
- Pure OWIN - usefull if you want to integrate with OWIN compatible module but not written in C#
- ASP.NET Core OWIN middleware
ASP.NET Core Middleware:
This type of middleware can be:
- delegate of
Func<HttpContext, Func<Task>, Task> - class with
IMiddlewareimlementation
app.Use(async (context, next) =>
{
// Do work that can write to the Response.
await next.Invoke();
// Do logging or other work that doesn't write to the Response.
});
Pure OWIN Middleware:
This rather would be used to integrate with OWIN middlewares written in different language, so that ASP.NET Core implementation directly is not possible.
Owin model and Kestrell request handling
- OWIN - Open Web Interface for .NET
- allows web apps to be decoupled from web servers
- defines standard way for middleware to be used in a pipeline to handle requests and provide responses
- ASP.NET Core applications can interoperate with OWIN-based applications, servers and middleware
Microsoft.AspNetCore.Owin package provides two adapter implementations:
- ASP.NET Core to OWIN
- OWIN to ASP.NET Core
This allows ASP.NET Core to be hosted on top of an OWIN compatible server/host or for other OWIN compatible components to be run on top of ASP.NET Core.
Expression Trees
- ’tree like’ data structure
- each node is expression (method call, equality comparison, binary operation etc.) representing a piece of code
- you can compile expression tree and run code it represent
- enables dynamic code generation at runtime
- LINQ queries on DBs are implemented with Expression Trees
- used in the dynamic language runtime (DLR)
- anonymous lambda expression can be converted to
ExpressionTreevia compiler (i.e.x => x*2can be represented as tree instead of delegate or anonymous lambda function)
Further read:
Linq
consistent model for working with data from various kinds of sources and formats (XML, SQL, ADO.NET, Datasets, .NET collections etc) 3 stages of working with LINQ: obtain data source create the query execute the query data sources implements IEnumerable<> and are called queryable types IQueryable<> interface inherits from IEnumerable<> generally it is better to use LINQ via IQueryable<> which produces deferred query instead of producing result immediately queries can be executed multiple times queries can be forced immediate execution via Count(), Max(), ToList() or ToArray() etc. LINQ to DB libraries (like EntityFramework) usually are implemented via Expression …
Entity Framework: Change Tracking
tracked entities are saved during SaveChanges() call entities being tracked when they are: returned from DB attached to context added as subentity tracking can be disabled (AsNoTracking() i.e.) Further read:
https://learn.microsoft.com/en-us/ef/core/change-tracking/
Entity Framework: eager and lazy loading
lazy loading:
- delaying load of data until we specifically request for it
- i.e. accessing
customer.Addressloads Address of a customer in the background via separate SQL query
- property needs to be public, virtual
- context.Configuration.ProxyCreationEnabled should be true
- context.Configuration.LazyLoadingEnabled should be true
- to disable lazy loading completely
Context.Configuration.LazyLoadingEnabled = false;
eager loading
- opposite of lazy loading
- loads related entities as part of the query
- done via
.Include()query
Further read:
Pattern matching
Pattern matching is used for:
testing expression to check if some value have certain characteristics safer compare because ‘==’ and ‘!=’ can be overloaded Examples:
a is int number sequence is IList<T> list switch statement:
command switch { Operation.SystemTest => RunDiagnostics(), Operation.Start => StartSystem(), Operation.Stop => StopSystem(), Operation.Reset => ResetToReady(), _ => throw new ArgumentException("Invalid enum value for command", nameof(command)), }; switch with ranges:
tempInFahrenheit switch { (> 32) and (< 212) => "liquid", < 32 => "solid", > 212 => "gas", 32 => …
Reflection
obtain information about types and members at runtime create instances, invoke or access them dynamic code generation Further read:
https://learn.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/reflection
Deployment models
Type Command framework-dependent executable for the current platform. dotnet publish framework-dependent executable for a specific platform. dotnet publish -r <RID> --self-contained false framework-dependent binary. dotnet publish self-contained executable. dotnet publish -r <RID> Further read:
https://learn.microsoft.com/en-us/dotnet/core/deploying/#publish-framework-dependent
.NET AOT
Ahead of the time compilation to machine code
produces self-contained application which: starts quicker uses less memory does not require .NET runtime installed it is better for workloads with high deployment instances (clouds) makes runtime code generation impossible not all libraries are compatible Further read:
https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/
.NET Jit
Just - in - time compiler.
part of CLR for all .net programs for all .net languages converts MSIL to native machine code compiles code when it is necessary at runtime also it is possible to pre-compile to native code at compile time instead Further read:
https://www.geeksforgeeks.org/what-is-just-in-time-jit-compiler-in-dot-net/
Records
can be class or struct creates methods overrides for enforcing value equality instead of reference equality: Object.Equals Object.GetHashCode operators == != implements IEquatable<> parameter implements ToString supports deconstruction supports with expression meant to be immutable Positional records is a more concise syntax for record:
primary constructor parameters match the positional parameters of the record declaration public init-only properties for each parameter Further read:
https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/records#characteristics-of-records
Is it possible to block GC?
We can.
for some critical part of application code using GC.TryStartNoGCRegion method. using CER (Constrained Execution Regions) (obsolete) with GC LatencyModes Further read:
https://learn.microsoft.com/en-us/dotnet/api/system.gc.trystartnogcregion?redirectedfrom=MSDN&view=net-7.0#overloads https://learn.microsoft.com/en-us/dotnet/framework/performance/constrained-execution-regions?redirectedfrom=MSDN https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/latency