Autofac is an IoC container which provides base class for user-defined modules. With Autofac, we can craete a ContainerBuilder and register components with it.
Implement DbContext, which is a combination of Unit of Work and Repository patterns
Implement Queries and Commands
To enable buld insert/update/delete, we can use an open-source lib: z.EntityFramework.Plus for entity framework core.
Application Project
Interface of Queries and Commands
Command: does something, should modify state, should not return a value
Query: answers a question, should not modify state, should return a state
Dtos: CreateDto, ModifyDto, etc
Manager Interface and Implementation
RESTful Api Project
Start and Program: Implement Config and ConfigService
Config CORS
Follow RESTful principles
Other supporting functions using query string: pagination, filtering, and searching
Paging: helps avoid performance issues
Filtering: Limits the collection resource, taking into account a predicate
Searching: Limits the collection resource by passing a search predicate
Hypermedia as the Engine of Application State (HATEOAS):
Functions:
Helps with evolvability and self-descriptiveness
Hypermedia drives how to consume and use the API
Working with Caching: Http Caching
Each response should define itself as cacheable or not
Cache types:
Client Cache: lives on the client private cache, reduces bandwidth requirements, and less requests from cache to API. i.e: Angular, Marvin.HttpCache, etc
Gateway cache: lives on the server shared cache, doesn't save bandwidth between cache and API, and drastically lowers requests to the API
Proxy cache: lives on the network shared cache
Expiration Model:
Validation Model: check the freshness of a response that has been cached
Strong validators: change if the body or headers of a response change, and can be used in any context
Weak validators: don't always change when the response changes
Combine Expiration Model and Validation Model
Add middleware to support cache header
Working with Concurrency
Pessimistic Concurrency:
Resource is locked
While it's locked, it cannot be modified by another client
This is not possible in REST
Optimistic concurrency:
Token is returned together with the resource
The update can happen as long as the token is still valid
ETags are used as validation tokens
Rate Limiting and Throtting: Limit the amount of allowed requests to API per hour/day per IP, etc.
Add middleware to configure the rate limit
Test Project
Unit of Work: Everything that happens from invoking a public method to it returning the results after it's finished. It's the work done along the path you see the debugger take through your code.
Unit Test: Single class, behavior, drive implementation, and fake data access layer
Integration Test: System, interaction, regression catch, test data access layer
Reinitialize database for every test run
Create before tests
Clean up after tests
Be resilient
Delete if it already exists
Close existing connections
Run migrations
EF6: MigrateDatabaseToLatestVersion
EF Core: Database.Migrate()
Test Names: Descriptive test names are very important, particularly as your test suites grow. A good practice is: [Subject][Scenario][Result], for example: GrantLoan_WhenCreditLessThan500_ReturnFalse.
Fake: a replacement of a real dependency with something the test specifies.
Requirements:
i). Read code >> Write Code
ii). Consistent, meaningful names
iii). Clear and simple tests
iv). Precise test scenarios: test one expectation per test; Multiple asserts on same object can be OK; Test should point to precise location of problem.
Infrastructure Project
Message: can be used to log any type of system messages: error, info, success, warning
ManagerResult: record the operation status with Message
File input & output
Some other functions that can be used to support the application
Improved performance: ASP.NET Core has better performance than ASP.NET
Side-by-side versioning.
ASP.NET Core allows multiple versions per machine
ASP.NET allows only one version per machine
New APIs: ASP.NET Core provides a lightweight, high-performance, and modular HTTP request pipeline that supports multiple data format and content negotiation, as well as model binding & model validation.
using third-party libraries or packages that not available for .NET Core
use .NET technologies that are not available for .NET Core
use a platform that doesn/t support .NET Core
ASP.NET Core Fundamentals
Overview:
Program.cs: create a web server in the Main method as a managed entry point for the app, and invokes CreateWebHostBuilder that create a web host and defines a web server.
Startup.cs: configure services required by the app and define the request handling pipeline. it contains two methods:
Configure: used to configure the HTTP request pipeline and defines the middleware called in the request pipeline.
used to specify how the app responds to HTTP requests
Adding middleware components to an IApplicationBuilder instance
ConfigureServices (optional): used to add services to the container including ASP.NET Core MVC, Entity Framework Core, Identity, etc. Called by the web host before the Configure method to configure the app's services.
Dependency Injection & Inversion of Control: ASP.NET Core provides a native IoC container that supports constructor injection by default. Services are made available through Dependency Injection (DI).
Middleware: in configure method, middleware can be added to the pipeline by invoking a UseXXX extension method. ASP.NET Core middleware performs asynchronous operations on an HttpContext and then either invokes the next middleware in the pipeline or terminates the request.
Logging.
Error handling.
Extend Startup with startup filters: Use IStartupFilter to configure middleware at the beginning or end of an app's Configure middleware pipeline. Middleware execution order is set by the order of IStartupFilter registrations.
Service lifetimes: Transient, Scoped, Singleton
Transient: services are created each time they are requested. This lifetime works best for lightweight, stateless services.
Scoped: Scoped lifetime services are created once per request. When using a scoped service in a middleware, inject the service into the Invoke or InvokeAsync method. Don't inject via constructor injection because it forces the service to behave like a singleton.
Singleton: Singleton lifetime services are created the first time they're requested (or when ConfigureServices is run and an instance is specified with the service registration). Every subsequent request uses the same instance.
Middleware: Middleware is software that's assembled into an app pipeline to handle requests and responses. Each component chooses whether to pass the request to the next component in the pipeline, and can perform work before and after the next component in the pipeline is invoked.
Create a middleware pipeline with IApplicationBuilder: The ASP.NET Core request pipeline consists of a sequence of request delegates, each delegate can perform operations before and after the next delegate. A delegate can also decide to not pass a request to the next delegate.
Middleware Order: The order that middleware components are added in the Startup.Configure method defines the order in which the middleware components are invoked on requests and the reverse order for the response. The order is critical for security, performance, and functionality.
Build-in middleware: Authentication, CORS, MVC, Session, etc.
Write Middleware: Middleware is generally encapsulated in a class and exposed with an extension method.