Monday, March 23, 2020

Top 10 Features Of Angular 7.0

Angular is one of the most popular frameworks for web application development. With the release of Angular 7, it has given even more angular features to web developers like including the core framework, Angular Material, CLI with synchronized major versions, along with toolchain, and has enabled several major partners launches. So we are highlighting some of its new features announced by the Angular Team. But not a lot of new features & updates introduced in this release, Angular 7 mainly focused on the Ivy project, rewriting the Angular compiler and runtime code to make it smaller, better, faster. But Ivy is not ready for prime time yet.

Let's jump to Top 10 Features & changes introduced in Angular 7

Angular 7 Features


CLI Prompts:

Angular CLI has updated to v7.0.2 added some features like now it will prompt users while typing common commands like ng-add or ng-new, @angular/material to help you discover built-in features like routing or SCSS support. With Angular 7, while creating new projects it takes advantage of Bundle Budgets in CLI.


Application performance:

Angular team discovered blemish that Angular developer were including the reflect-metadata polyfill in production, which is only needed in development, In order to fix this, part of the update to v7 will automatically remove it from your polyfills.ts file, and then include it as a build step when building your application in JIT mode, removing this polyfill from production builds by default.To speed up the performance new applications will warn when the initial bundle is more than 2MB and will error at 5MB which the user can modify it in angular.json file. These budgets align with warnings that can be shown to users taking advantage of Chrome’s Data Saver features.

Angular 7 Performance


Angular Material & the CDK

Angular Material and the Component Dev Kit (CDK), Angular 7 features visual improvements in Material Design which received a major update in 2018, refresh as well as virtual scrolling, for dynamically loading and unloading parts of the DOM to build high-performing, large lists of data. Also, applications can be fitted with a drag-and-drop capability by importing the DragDropModule or the ScrollingModule.
  • Virtual Scrolling
Virtual Scrolling
The scrolling package <cdk-virtual-scroll-viewport> provides helpers for directives that react to scroll events. Virtual Scrolling enables loading and unloading elements from the DOM based on the visible parts. It enables a performant way to simulate all items being rendered by making the height of the container element the same as the height of a total number of elements to be rendered, and then only rendering the items in view makes very fast experiences for users with very large scrollable lists.
  • Drag and Drop
Drag and DropThe @angular/cdk/drag-drop module provides you with a way to easily and declaratively create drag-and-drop interfaces, with support for free dragging, sorting within a list, transferring items between lists, animations, touch devices, custom drag handles, previews, and placeholders, in addition helper methods for reordering lists (moveItemInArray) and transferring items between lists (transferArrayItem).

Angular Compatibility Compiler (ngcc)

Just like the name suggests, this compiler will be used to transform the node_modules compiled with the ngc to node_modules which are compatible with the new Ivy renderer. Angular Compatibility compiler converts node_moduls compiled with ngc, into node_modules which appear to have been compiled with ngtsc. This conversion will allow such “legacy” packages to be used by the Ivy rendering engine.
  • Angular Do-Bootstrap
It's used for bootstrapping modules that need to bootstrap a component. Angular 7 added a new life-cycle hook (ngDoBootstrap) and interface (DoBootstrap).For example

Angular Do-bootstrap
  • Better Error Handling
Angular 7 has an improved error handling for @Output if property is not initialized.

Dependency Updates In Angular 7

  • TypeScript 3.1 support
    Angular 7 have updated TypeScript version from 2.7 to 3.1 which is it's the latest release. It's compulsory to use TypeScript's latest version while working with Angular 7. Usually Angular lags a few releases behind, so they have done that to match latest TypeScript version for once.
    • RxJS 6.3
      The latest version of RxJs(version 6.3.3) is added in Angular 7 with its new exciting additions and changes. These Angular 7 changes provide developers a boost in performance and easier to debug call stacks and improvement in modularity also making it as backward compatible as possible.
    • Added Support for Node v10Added Support for Node v10
      Team Angular 7 now supports the Node V10 with backward compatibility as well, check out what's new in Node v10.

    Angular Elements with Slot

    Angular 6.1 enables the feature of ViewEncapsulation.ShadowDom, which is great for Angular Elements which now supports content projection using web standards for custom elements. A new standard HTML element, introduced by the Web Component Specification which is a slot. This feature is now available, enabling components with a template.
    Slot With Elements

    That can later be used as an Angular Element like this:
    Slot With Elements


    New ng-compiler

    New ng-compiler provides an accelerated eight-phase compilation and reduction of large app size approximately 2 times. The new compiler is capable of advanced 8-phase rotating ahead-of-time compilation. Most applications can expect a massive reduction of 95-99% in bundle sizes.

    Splitting of @angular/core

    One of the disadvantages of Angular is its total multipurposeness. It’s a large framework itself automatically provides modules which you probably don’t need, thus team Angular has split @angular/core past the boundaries presented no less than 418 modules.

    Router

    A new warning has been added if you try to trigger navigation outside of the Angular zone, As it doesn’t work if you do so, Angular now logs a warning (only in development mode). Also add navigation execution context info to activation hooks.


    Still no Ivy

    The Angular team won't commit to a final timeline but according to the official blog post, Ivy is still under active development and is not part of the v7 release. They note backward compatibility validation began with the exciting application and we are expecting a complete beta to launch somewhere in version 8. Follow the progress yourself on the GitHub Ivy Renderer issue under the official Angular repo. The best news? They fully expect that Ivy can be released in a minor release as long as it's fully tested and validated. Maybe we'll see it in the next version of Angular 7.

    ivy-release-chart


    Documentation updates

    The documentation on angular.io now updated the reference material for the Angular CLI.


    Deprecations

    Few things have been deprecated in angular latest version 7 like If you were using <ngForm> to declare a form in your template (you don’t have to, as form also activates the NgForm directive), this selector is now deprecated and should be replaced by <ng-form>.


    How to update to Angular 7

    If you are on already running your Angular App on Angular 6 & RXJS 6, just update your @angular cli/core and also update your angular material.

    Angular 7 Features & Updates

    Angular 7 Features & Updates
    Or Visit update.angular.io for detailed information and guidance on updating your application. Developers have reported that Angular 7 update is faster than ever, and many apps take less than 10 minutes to update.

    Check out More of the Angular 7 New Features Below:

    • Angular Console — A downloadable console for starting and running Angular projects on your local machine
    • @angular/fire — AngularFire has a new home on npm, and has its first stable release for Angular
    • NativeScript — It’s now possible to have a single project that builds for both web and installed mobile with NativeScript
    • StackBlitz — StackBlitz 2.0 has been released and now includes the Angular Language Service and more features like tabbed editing
    • Improved Accessibility of Selects (selectelement inside of a mat-form-field)
    • bazel: Initial commit of protractor_web_test_suite
    • compiler-cli: update tsickle to 0.29.x
    • core: export defaultKeyValueDiffers to private API
    • Platform-Browser: add HammerJS lazy-loader symbols to public API
    • Service-Worker: add support for ? in SW config globbing

    Conclusion: 
    Summing up all the above features, Angular v7 looks like a much more accessible solution focused on the modern technological trends added features like bitcoin mining, Virtual scrolling, drag-drop, Angular material and many more, still no word on Ivy in a current version. Angular Team has done some great job for making Angular better. If you are planning on implementing your own solution based on the web & mobile technologies, make sure to consider Angular 7 as the efficient, up-to-date development framework.


    The user interface for mobile and web applications is mostly through Angular JavaScript and now Angular 7 is the latest version developed with a minor 2 version and level 11 in the patch. The next version may be launched soon.
    Built With summarizes that around 93,333 websites are using Angular versions out of which about 20,422 are using Angular lively and 70,511 sites have been estimated to use the JavaScript in the past. The major contributors for the same are
    • The United States with approximately 13,866 websites
    • Germany with around 733
    • France with 490 approximately
    • Brazil estimates to 463
    • .io with about 403

    PROBLEM BEHIND THE OLD VERSION OF ANGULAR:

    Here are some interesting rumors about the Angular JavaScript that got users confused while developing interfaces for Android, IOS, Windows, Linux, and Mac.
    • LINKED TO ARTIFICIAL INTELLIGENCE

    Some rumors went viral that Angular features included storage in artificial intelligence or AI format with a unique factor of being compatible backward with a code base of NgRx.
    • SPLITTING OF CORE OR ANGULAR

    The rumors also stated that the core or angular splitting package was responsible for the bundle size of an application as well as performance pertaining to a cold start.
    • THE FEATURE OF AN NG-COMPILER

    It also was heard that Angular included extensive features which can enable the compression or reduction of application bundle sizes from 95 to 99% approximately.
    Therefore the true features and updates of Angular 7 are explained below in a way that rumors and fake news stay away and facts do the talking.

    FEATURES OF ANGULAR 7:

    • FOCUSED ON THE IVY PROJECT

    The Angular 7 release date was October 18, 2018, which was mainly built for the Ivy project. The question which strikes the mind next is, “What is the Ivy Project?”
    The answer to this is that in an initiative to rewrite or modify the Angular compiler along with modifying and updating the runtime code Ivy Project was introduced. This, in turn, makes Angular 7 speedy, improvised, and portable.
    • THE COMMAND-LINE PROMPT FEATURE

    This particular feature has been upgraded to version 7 with level 2 in the patch. While using this version of Angular JavaScript, there are actually prompts when
    1. A command for either material or Angular is put
    2. The Ng-new command and
    3. Command of Ng-add
    This, in turn, helps a particular developer or a coder to explore the features of routing, support, a new syntax of SCSS which is supported by SASS and has been built into Angular.
    • IMPROVISED MATERIAL DESIGN WITH AN ADVANCED DEVELOPMENT KIT

    With the introduction of Angular 7 came in visual updates in minority for platforms such as web and mobile and the respective operating systems like Android and IOS. The material design for Angular has also been modified and upgraded to a higher version. Further, the component development kit or the CDK and the Angular Material include
    1. Option to refresh
    2. Virtual scrolling, which is also one of the unique Angular Js features
    3. Dynamic data list
    4. Loading and unloading of parts of Document Object Model or the DOM in a dynamic way
    • THE FAMOUS DRAG AND DROP MODULE

    This feature has been developed from the traditional drag and drops Angular Js which was included in the first version of Angular. This is possible with version 7 also with the help of drag and drop module and scrolling module being imported into it.
    The drag and drop module specifically enhances the dragging and dropping facility in interfaces with the back-up feature of sorting in the boundaries of a certain list. There are a few more functionalities which the Angular7 supports in this domain
    1. The dragging is free and is supported at the back end
    2. Some animations
    3. The drag handles can be customized
    4. Dragging and dropping items from one list to the other
    5. Review or preview the whole thing before finalizing it
    6. Also supportive placeholder texts
    7. Activates a unique high-performance technique through which the height of the element which acts as the container turns equal to the total amount of rendering elements
    8. Enhances visibility in a way that the users of the applications can have speedier and hassle-free experiences
    The CDK or the component development kit includes the drag and drops feature in a supportive format with an additional format of rendering automatically when the relocation of items is done by the users.
    • DEVELOPMENTS IN THE PERFORMANCE OF APPLICATIONS

    Research reads that while improvising the performance of Google, the research and development crew diagnose that web developers were mostly using the metadata which was in the reflect format. Hence, a part of the Angular 7 has been integrated to delete the same from a file formatted like polyfills.ts.
    • THE NGCC OR THE ANGULAR COMPATIBILITY COMPILER

    This particular feature comes in handy when the node modules developed through ngcc needs to be transformed into a format compatible with that of the Ivy project. This indicates that the node modules shall convert from a format of ngc to ngtsc. The Ivy rendering engine shall make use of packages like
    1. Do-Bootstrap for Angular which mainly aims at bootstrapping modules through a customized ngDoBootstrap as well as DoBootstrap interface.
    2. Improvised error handling for the output if initialization of the property is not done in a proper manner.

    UPDATES FOR DEPENDENCY IN ANGULAR 7:

    There are three updates for Angular current version with regards to dependency
    • SUPPORT FOR TYPESCRIPT 3.1

    The TypeScript 3.1 has been upgraded from its 2.7 version by Angular7and is mandatory for use while working or developing applications with the help of Angular 7. The reason behind such an update is that Angular 7 moves slowly in term of TypeScript releases for coding.
    • THE RXJS 6.3 JAVASCRIPT VERSION

    Similar to the above, RxJs also has been upgraded to a version of 6.3.3 with new updates and modifications which encourage performance boosting for developers. The ability for debugging call stacks and developed modularity shall enable the compatibility of Angular 7 in a backward format also.
    • NODE V10 AS THE CHERRY ON THE TOP

    Angular 7 is highly supportive with Node v10 along with backward compatibility to give a power packed performance for developing mobile as well as web applications across servers and platforms.
    • ELEMENTS OF ANGULAR WITH SLOT

    A yet another unique feature of Angular 6.1 is the ‘ViewEncapsulation.ShadowDom’ which with the support of web standards can implement projection of content in a customized manner. The slot is a fresh element standardized by HTML and produced by the WCS or the Web Component Specification. The same feature is also available for components enabling with the support of a template.
    • UPDATED ROUTER AND UPDATES FOR DOCUMENTATION

    The new and improvised router has got features such as logging a caution or warning if the navigation is triggered outside the zone pertaining to the Angular Js. The same feature should be added for activation hooks for developing the applications across all operating systems and platforms for seamless and hassle-free development.
    The information regarding Angular Code-Line has been updated on Angular.io as documentation.
    • ALTERATIONS

    Some of the codes have been altered for the latest Angular 7 versions. For example, if <ngform> was used for form declaration in a particular template, the code should not be used as it may activate the directive for NgForm. Instead of that, <ng-form> should be used as the appropriate code.
    But apart from all these features, there still is a need to update Angular. This is because the Angular application is not automated and cannot update itself through just permissions like a mobile or a web application. Hence, here are a couple of commands which may come handy for upgrading the coding language
    1. If a particular Angular application is running on a version 6 as well as RxJs 6, then it is quite suggested that the code-line or the core should get updated along with the Angular material.
    2. The coding for the same is $ ng update @angular/cli @angular/core and $ ng update @angular/material
    3. As an alternative, it is also suggested to visit Angular.io for updating the version
    4. Research reads that the update process is faster for Angular 7 which is approximately less than ten minutes.

    ADDITIONAL FEATURES PERTAINING TO ANGULAR 7 ARE:

    • CONSOLE FOR ANGULAR

    Consoles for running and commencing Angular projects on either laptops or desktops are available for download from the internet in a way that Angular can work at home without any obstacles or hassles
    • ANGULAR IS ON FIRE

    Npm supports a module known as Angular fire which is compatible with Angular7. It is also stable for use for developing applications for mobile and web
    • BRIDGING THE GAP BETWEEN MOBILE AND WEB THROUGH NATIVESCRIPT

    This is a new feature which has been included in Angular 7 which can enable single project development for mobile platforms such as Android and IOS as well as web platforms like Windows, Mac, and Linux
    • INCLUDES FEATURES LIKE STACKBLITZ

    StackBlitz has been upgraded to version 2 to support the Angular 7 language for coding and development with advanced features like editing through tabs is made possible
    • FEATURING BAZEL

    Bazel is prior to the software for web testing also known as ‘web test suite’ and the whole thing is known as ‘protractor web test suite’ for reference which makes the entire application efficient and  robust
    • ANGULAR CORE

    The private Application Programming Interface or the API shall need an export of ‘defaultKeyValueDiffers’.
    • ANGULAR PLATFORM TO BROWSER COMMANDMENT

    For the public API or the Application Programming Interface, Hammer Js should be used in the form of lazy-loader for efficiency and compatibility
    • CODE-LINE COMPILER

    0.29.x version has been updated from tsickle for a hassle-free and seamless CLI compilation
    • ANGULAR SERVICE-WORKER

    For enabling a robust and durable mobile or web applications, a certain service- worker setting, and configuration is required. And for enabling the same, support for ‘?’ should be added to the service worker’s configuration and settings in a way that the entire set up runs smoothly

    CONCLUSION

    Hence, here are the best Angular 7 features which shall help in using and installing the appropriate Angular versions on the devices in a way that a suitable application and user interface can be developed with the required features and updates for providing a seamless performance with strong and efficient desired outputs from the same.
    Also, Android 7.0 features are developed by using Angular JavaScript and not any other secret formulae or rocket science is responsible for the same. Apart from these, the upgraded versions of Angular 7 may be introduced soon for enabling developers to build a robust and durable application for the web and the mobile.

    New Features of Angular 8.0

    Differential Loading of JavaScript 

    Differential loading enables browsers to select optimized or legacy bundles according to their capabilities and then automatically load the correct one. Users then receive the bundle(s) they require based on their specific needs. 
    In the latest version, Angular serves different browsers with different bundles, and this is by default. The CLI extensions generate different bundles for old legacy (ES5) browsers and modern JavaScript (ES2015+) browsers. 
    Moreover, it enhances the loading speed and the time to interactive (TTI) for a modern browser. The speed of applications and building a process takes place by using polyfills or modern syntax. Moreover, differential loading also helps in saving 7 to 20 percent of bundle size on average. 
    Differential loading in Angular 8.0 forms a part of Manfred Steyer's project, ngx-build-modern. All bundling is done with the ng build command and the -prod extension, without requiring special actions.
    You may also like: Angular: Everything You Need to Know [Tutorials].

    Opt-In Usage Sharing

    It acts as an addition to the Angular CLI that aligns Angular 8 with community needs. Angular needs to keep a tab on how developers use the platform and what improvements are required. This is done with the information on the command used and builds speed. You can share telemetry on CLI usage with your development team. 
    Angular emphasizes consent on data sharing, unlike other platforms that collect data by default on an opt-out basis. It stops when you command them not to. Others don’t even allow them to ask them to share telemetry. 

    Improved Web Worker Bundling 

    With CPU-intensive tasks, the best way to speed up the application and improve parallelizability is web workers. Web workers write code off the main thread and offload tasks to a background thread. 
    The code running in the web worker cannot exist in the same JavaScript file in the application. These two must be different. Those working with tools such as Angular CLI bundles JavaScript automatically into a as few files as possible. 
    With the new improvements, Angular 8.0 makes it possible to fully parallelized web worker bundling. It acts as a relief for front-end developers who face limitations in single-thread.  
    You can run the following if you want to create a new CLI with a web worker. 

    Ng Generate Web Worker My-Worker

    On receiving the web worker, adopt the process to implement the web worker in your application. It is then bundled and code-split with the following line:
    const worker = new Worker(`./my-worker.worker`, { type: `module` });

    Angular Router Backwards Compatibility

    Angular 8 comes with a backward compatibility mode which makes it simpler to upgrade the larger applications. The teams move to Angular with lazy loading of the AngularJS-based app’s parts, using the $route APIs. 

    FORMS

    MarkAllAsTouched

     MarkAllAsTouched is a method in Angular 8 used in the AbstractControl class. 
    It adds to the list of previous methods, such as  markAsDirty,  markAsTouched, and  markAsPending. The method gets available in all reactive form entities, since AbstractControl is the parent class of FormArrayFormGroup, and FormControl
    The method touches marks control and descendants as touched as shown below: 
    form.markAllAsTouched();

    FormArray.clear

    In Angular 8, the FormArray class offers a clear method, which quickly removes all control it contains. You no longer have to loop over every control one-by-one, as shown below:
    // `users` is initialized with 2 users
    const users = fb.array([user1, user2]);
    users.clear();
    // users is now empty

    ROUTER 

    Location

    To migrate to Angular 8, you should be aware of a few things added to the location services:
    • Offer access to the hostname, port, and protocol with platformLocation
    • Get history.state with the new getState() method. 
    • Ease testing with a MockPlatformLocation

    Lazy-Loading With Import Syntax

    Lazy loading is a useful concept in Angular 8. It brings down the size of occasionally used files. It uses the standard dynamic import syntax from TypeScript, instead of the custom-string for lazy-loaded modules. The syntax has similarities with ECMAScript standard and supported only by Ivy. 
    So, what earlier looked like: 
    { path: '/student', loadChildren: './student/student.module#StudentModule' }  
    Now, looks as:
    { path: '/student', loadChildren: () => import('./student/student.module').then(s => s.StudentModule) }

    Service Worker

    A service worker in Angular is a script that runs in a web browser and manages cache for an application. It augments the traditional web deployment model and empowers the application to deliver a reliable user experience with performance on par with natively-installed code. 

    Registration Strategy

    In previous versions, the Service worker was waiting for a stable application to register. This was used to avoid slowing the start of an application. The new option has an option that specifies when the registration will take place.
    However, if starting a recurring asynchronous task in the previous versions would never be considered by Angular as stable, the service work would not have registered. 
    But, with Angular 8, this is possible with the option of registrationStrategy for handling the registration for a service worker with the following values:
    • The default value is registerWhenStable
    • Register immediately with registerImmediately, with no need to wait for the app and registers, right away. 
    • Delay in milliseconds in $TIMEOUT with registerDelay:$TIMEOUT
    • A custom strategy defines a return value as Observable. The Service Worker registers with the first value of the Observable.
    Here is code snippet for Service Worker registration after 4 seconds:

    Bypass a Service Worker 

    You can use the ngsw-bypass header, for bypassing the service worker with a specified request, as shown in the below code:
    this.http.get(‘api/users’, { headers: { ‘ngsw-bypass’: true } });

    Multiple Apps on SubDomains

    Earlier it was not possible to use multiple applications for using @angular/service-worker with different sub-paths for the same domain. It was because the cache of each service worker overwrote the cache of others. This error gets fixed in this version. 

    TypeScript 3.4 

    It is now mandatory for Angular 8 to use TypeScript 3.4. The development team must upgrade the TypeScript. It helps when using readable and clean JavaScript code. TypeScript 3.4 introduces a new flag named incremental. It saves information from the project graph from the last compilation. While using Incremental, the information detects the least costly way to emit changes for your project and type-check. 

    Workspace APIs and Builder APIs in CLI 

    Angular 8 has new builder APIs to tap ng build, ng test, and ng run. It has similarities with schematics that taps into ng addng generateng update, and  ng new
    It uses third-party tools and libraries to assist you in processes such as building and deployment. Moreover, Angular leverages Cloud for APIs. AngularFire is the official library that connects Angular with Firebase. AngularFire adds the deploy command to simplify the process of deployment and build by Firebase with the following: 
    ng add @angular/fire
    ng run my-app:deploy

    Moreover, in earlier version, for changes in workspace configuration, angular.json was modified manually using Schematics. But the new API, in the current version, makes it simpler to modify and read a file.  
    AngularJS Migration 
    Angular 8 enables the users of $location services, as it now allows a Location Upgrade Module in the AngularJS applications. It helps to translate the unified location service and shifts the responsibility from AngularJS $location to the Angular Location. It eases our applications with hybrid operations and depends on the upgrade along with route in AngularJS and part. 
    Bazel 
    The latest Angular version makes it easier to build CLI applications. All this is due to Bazel, developed by Google. It is a build tool that works well with any language inputs. Some benefits of Bazel are:
    • Build frontend and backend with the same tool.
    • Gain on rebuild time with tests and incremental builds. 
    • Gain cache and remote builds on build farms. 
    • Allow tasks with clear input or output with Bazel and ensure that all the necessary tasks run. 

    About IVY 

    Ivy is the prime feature of Angular 8 and included as an opt-in preview for testing. Ivy is a new compiler to build next-gen rendering pipelines in the current version. It increases the efficiency of the latest version. It helps to improve runtime speed with simplified incremental compiling with its ability to generate bundles of significantly smaller size. 
    Moreover, it uses the concept of incremental DOM, where each component gets compiled with a set of instructions that constitutes the DOM tree. It updates it with a change in data. 
    Developers can use Ivy to determine the potential and performance of Angular applications. It never alters any of the existing applications. On completion, it will make the Angular applications smaller, simpler, and faster. 

    Two Primary Concepts of Ivy

    Local : Recompile only the changed components and allow quicker compiling. 
    Treeshakable: The unused code gets removed so that the application concentrates on the code used. Ivy acts beneficially when the UI of the application is clear to the developer. 

    Advantages of IVY

    The advantages of Ivy are:
    • Smaller Bundles.
    • Reduced Payload Size.
    • Faster Rebuild times.
    • Enhance Backwards Compatibility .
    • Pre-compiled Code shipment .
    • Dismissal of metadata.json.
    • Rise of meta programming.
    • Improve template type checking.
    • Broad Compatibility with existing Angular applications.
    Notable Changes 
    The angular team makes your life easier with Schematics. Schematic updates your code by simply running:
    ng update @angular/cor

    Query Timing 
    The decorators, ViewChild and ContentChild, now have a new option called static. If the queried element is static (not wrapped in ngIf and ngFor. Thenm, it is available in ngOnInit:
    So,
    <h1 #staticDiv>static</h1>
    Gives
    @ViewChild('staticDiv') staticDiv: ElementRef<HTMLDivElement>;
    ngOnInit() {
      console.log('init static', this.staticDiv); // div
    }
    ngAfterViewInit() {
      console.log('after view init static', this.staticDiv); // div
    }

    A static flag, when introduced, not only breaks existing applications, but you can use the following to keep the old behavior, even when switching to Ivy. It ensures the same behavior as the current one. 
    @ViewChild('static', { static: true }) static: ElementRef<HTMLDivElement>;

    You can check with the query migration guide for further information.

    Template Variable ReAssignment

    View Engine allowed the following:
    <button
      *ngFor="let option of options"
      (click)="option = 'newButtonText'">{{ option }}</button>

    However, this is no longer possible in Ivy. It does not allow us to assign a value to a template variable like an option in the above example. 
    When you upgrade to Angular 8 to prepare for the switch to Ivy, a schematic analyzes the template and issues a warning for such a case. 
    The option left is to fix it manually.
    <button
      *ngFor="let option of options; index as index"
      (click)="options[index] = 'newButtonText'">{{ option }}</button>

    Document 

    The token DOCUMENT gets moved from the @angular/platform-browser to  @angular/common. It is manually possible to change it with a schematic provided for the purpose. 

    Remove Deprecated HTTP Package 

    Angular 8 removed @angular/http replaced with @angular/common/http as in Angular 4.3. A schematic removes the dependency in package.json. 

    Deprecated Web Worker Package 

    The @angular/common/http package enables you to run an application in the Web Worker. It is included in the deprecated packages list and will be removed in the future. 
    You can find the list of all deprecated API packages obtained here. 

    How to Update Angular 7 to Angular 8

    Some of the things to consider are:
    • TypeScript 3.4 may cause some syntax error.
    • Run the $ node-vcommand to check the version of Node running in your system. You need to run Node 12 and beyond for the upgrade.
    • Run $ ng update @angular/material to run the Angular Material in the application.

    Conclusion 

    Other than Ivy, the additions to Angular 8 are not that critical or significant. You can gather insights on the Ivy preview from the official Ivy guide provided. However, it is recommended to upgrade to Angular 8 to ensure that your apps are all ready for Ivy. 
    Moreover, Ivy will become the default in the next version of Angular, so now it the best option for you to check whether your apps are going to need any changes. 
    Angular 8 has been out a few months now, and includes a handful of useful new features developers are already putting to good use. Google’s popular client-side web framework continues to evolve, and the latest major release includes features that focus on performance, stability and tooling.
    Here’s a list of the top 5 new features in the framework, along with a bonus teaser at the end. There should be plenty of new features here to help you build better apps today and give you reason to be excited about the future of Angular.

    1. Differential loading

    Differential loading is a new feature that lets you use version 8 of the Angular CLI to create two different production bundles of your app. Attributes on the <script> tag in your index.html file let the browser request the most appropriate bundle; modern browsers will request a bundle that uses ES2015 JavaScript syntax and will be significantly smaller than the legacy bundle that uses ES5 syntax to maintain support for older browsers. Differential loading is enabled by default for new apps created with version 8 of the CLI, but you can easily enable this feature on your existing apps by upgrading to Angular 8, adding a browserlist configuration file, and setting the “target” option in your tsconfig.json file to “es2015”. The result? Your users with modern browsers get a smaller bundle that loads faster (and puts a bigger smile on their face).

    2. New lazy loading syntax

    Lazy loading feature modules has been a best practice in Angular for quite a while. That hasn’t changed in version 8, but in place of the proprietary syntax to enable lazy loading, the framework has adopted the more common dynamic import syntax used widely in client-side web development. The new syntax relies less on parsing class names from strings and enables editors and IDEs to check that you’re importing the correct items.

    3. Create web workers with the CLI

    Angular 8 makes it easier than ever to use web workers to handle CPU-intensive tasks in your apps. Version 8 of the Angular CLI includes a new schematic used with the ng generate command to create and update the necessary files in your project to add a new web worker. The new and updated files include a basic template for your new web worker so you can worry less about boilerplate syntax and more quickly focus on writing the code you want to run on a background thread.

    4. Builder and workspace APIs

    Although they’re probably not a feature you’ll use on every project, Angular 8 also includes new APIs that allow you to create custom build and deployment commands using hooks into the familiar ng build, ng test, and ng run commands. There are also new APIs that allow you to open and work with the workspace defined in your angular.json file, which should reduce the amount of manual manipulation required to perfectly configure your project.

    5. A new guide for old features

    The Angular team included a new deprecation guide with Angular 8 to make it easier for developers to keep track of deprecated features and APIs. The creation of this guide should not be misinterpreted as a warning that deprecations will be sprung on the developer community with little time for remediation. In fact, the Angular team is committed to supporting features for two major releases after officially being deprecated. The resulting stability in the framework coupled with the helpful deprecation guide should smooth the transition away from those older features.

    On the horizon: Ivy and Bazel

    Two of the most highly-anticipated and new features in Angular didn’t actually make it into version 8, but you can try them both out using a new opt-in preview.
    Ivy is the code name given to the next-generation compilation and rendering pipeline. The goal with Ivy is to produce smaller, faster application bundles in a way that is transparent to developers using the current rendering pipeline. Bazel is an open-source build and test tool used extensively at Google. The Angular team is working to integrate Bazel into the standard Angular toolset to enable developers to perform faster incremental builds on large projects. Although they aren’t ready for production use, you can opt-in to both tools and take them for a test drive if you’re anxious to see what they offer.
    Install Angular 8 today and give it a try! The present and future of the framework appear as bright as ever.

    Advanced Use Cases for the Repository Pattern in .NET


    Key takeaways

    • Repositories make sense when you are doing more than basic CRUD.
    • To facilitate testing and improve reliability, repositories should be treated as reusable libraries.
    • Moving security and auditing into the repository can reduce bugs and simplify your application.
    • Your ORM choice doesn’t limit what your repository can do, just how much work it will take to do it.
    In our previous article, Implementation Strategies for the Repository Pattern with Entity Framework, Dapper, and Chain, we looked at the basic patterns needed to implement a repository. In many cases these patterns were such a thin layer around the underlying data access technology they were essentially unnecessary. However, once you have a repository in place, many new opportunities become available.
    When designing a repository, you should be thinking in terms of “what must happen”. For example, let us say you have a rule that whenever a record is updated, its “LastModifiedBy” column must be set to the current user. Rather than trying to remember to update the LastModifiedBy in application code before every save, you can bake that functionality right into the repository.
    By treating your data access layer as a standalone library that manages all of the “must happen” details, you can dramatically reduce implementation errors. At the same time, you can simplify the code that is built on top of the repository, as it no longer needs to be concerned about bookkeeping tasks.
    Note: where appropriate, this article will include code samples for Entity FrameworkDapper, and/or Tortuga Chain. However, you will find most repository features can be implemented in an ORM-agnostic fashion.

    Audit Columns

    Most applications eventually find the need to track who made changes to the database and when. For simple databases this takes the form of audit columns. The names vary, but they usually fall into these four roles:
    • Created by User Key
    • Created Date/Time
    • Last Modified by User Key
    • Last Modified Date/Time
    Depending on the security requirements of the application, additional audit columns may be considered such as:
    • Deleted by User Key
    • Deleted Date/Time
    • [Created | Last Modified | Deleted] by Application Key
    • [Created | Last Modified | Deleted] by IP Address
    The date columns are easy enough to handle behind the scenes, but for the user keys you need to do something a bit more interesting. What you need is a “context aware repository”.
    Normally repositories are context free, meaning they have no information other than what’s absolutely necessary to connect to the database. When correctly designed, the repository can be entirely stateless, allowing you to share one instance across the whole application.
    Context aware repositories are a bit more complex. They cannot be constructed until you know the context, which at the very least includes the currently active user’s id or key. For some applications, this is enough. For others, you may need to pass in an entire user object and/or an object representing the running application.

    Chain

    Chain has built in support through a concept known as audit rules. Audit rules allow you to specify overrides based on a column name. Out of the box, it includes date-based rules and rules that copy a property from a user object into a column. Here is an example,
    dataSource = dataSource.WithRules(
        new UserDataRule("CreatedByKey", "UserKey", OperationType.Insert),
        new UserDataRule("UpdatedByKey", "UserKey", OperationType.InsertOrUpdate),
        new DateTimeRule("CreatedDate", DateTimeKind.Local, OperationType.Insert),
        new DateTimeRule("UpdatedDate", DateTimeKind.Local, OperationType.InsertOrUpdate)
        );
    As mentioned above, you are going to need a context aware repository for this to work. In the constructor below you can see how the context is passed to an immutable data source, creating a new data source with the necessary information.
    public EmployeeRepository(DataSource dataSource, User user)
    {
        m_DataSource = dataSource.WithUser(user);
    }
    Thus setup, you can leverage your DI framework of choice to automatically create and populate the repository on a per-request basis.

    Entity Framework

    To globally apply audit columns in Entity Framework, you need to leverage the ObjectStateManager and create a specialized interface. The interface, or base class if you prefer, will look something like this:
    public interface IAuditableEntity 
    {
        DateTime CreatedDate {get; set;}
        DateTime UpdatedDate {get; set;}
        DateTime CreatedDate {get; set;}
        DateTime CreatedDate {get; set;}
    }
    The interface (or base class) is then applied to every entity for which the database has matching audit columns.
    Next you need to override the Save method of your DataContext class as follows.
    public override int SaveChanges()
    {
        // Get added entries
        IEnumerable<ObjectStateEntry> addedEntryCollection = Context
            .ObjectContext
            .ObjectStateManager
            .GetObjectStateEntries(EntityState.Added)
            .Where(m => m != null && m.Entity != null);
    
        // Get modified entries
        IEnumerable<ObjectStateEntry> modifiedEntryCollection = Context
            .ObjectContext
            .ObjectStateManager
            .GetObjectStateEntries(EntityState.Modified)
            .Where(m => m != null && m.Entity != null);
    
        // Set audit fields of added entries
        foreach (ObjectStateEntry entry in addedEntryCollection)
        {                
            var addedEntity = entry.Entity as IAuditableEntity;
            if (addedEntity != null)
            {
                addedEntity.CreatedDate = DateTime.Now;
                addedEntity.CreatedByKey = m_User.UserKey;
                addedEntity.UpdatedDate = DateTime.Now;
                addedEntity.UpdatedByKey = m_User.UserKey;
            }
    
        }
    
        // Set audit fields of modified entries
        foreach (ObjectStateEntry entry in modifiedEntryCollection)
        {
            var modifiedEntity = entry.Entity as IAuditableEntity;
            if (modifiedEntity != null)
            {
                modifiedEntity.UpdatedDate = DateTime.Now;
                modifiedEntity.UpdatedByKey = m_User.UserKey;
            }
        }
        return SaveChanges();
    }
    If you are going to be working a lot with EF, it really pays to become intimately familiar with the ObjectStateManager and its capabilities. This is where most of the useful metadata about transactions in progress can be found.
    Finally, you need to modify the constructor of your data context (and possibly repository) to accept a user object.
    While this looks like a lot of code, it only needs to be done once per EF data context. And as with the previous example, the actual creation of the data context and repository can be performed by your DI framework.

    History Table

    Tracking changes to records is often required due to local laws and regulations. Other times it is desirable simply to make diagnostics easier.
    Our general recommendation is to simply allow the database to do this. Some databases have this capability built-in, which is often referred to as a temporal table. Others can emulate it using triggers. In either case, the application is unaware of the additional logging, which makes the technique far less error prone.
    If for some reason you cannot use a temporal table or trigger, then the repository needs to explicitly write to the history table.
    Regardless of where you put the code that maintains the history table, there are two basic conventions that you can follow. Consistency is really important here, as it would be quite confusing to have one convention for some tables and the other convention for the rest.
    Copy before Write: In this convention you copy the old record from live table to the history table prior to performing the update or delete operation. This means the history table never contains the current record. As a result, you’ll need to join the live and history tables together to see a complete history of changes.
    Write before Copy: Alternately you can update the live table first, then copy that row to the history table. This has the advantage of having a complete picture in the history table, eliminating the aforementioned join. The downside is it takes more space due to the duplicated data.
    With either convention, you’ll want to use soft deletes in order to track who is actually deleting the row. If hard deletes are desired, then they should only be performed following a soft delete.

    Soft Deletes

    One of the advantages of using a repository is you can switch from hard deletes to soft deletes without the rest of the application realizing it. A soft delete removes the record as far as the application is concerned, but allows it to remain in the database for auditing purposes. Optionally, an application can even undelete records.
    To avoid data loss, applications should not be granted DELETE privileges on tables that support soft deletes. If the application accidentally tries to perform a hard delete, the permission check will raise an error instead of silently deleting the row.

    Chain

    Chain offers implicit soft delete support via the audit rules infrastructure. When configuring a soft delete rule, it is customary to also configure the matching audit columns:
    var dataSource = dataSource.WithRules(
        new SoftDeleteRule("DeletedFlag", true, OperationTypes.SelectOrDelete),
        new UserDataRule("DeletedByKey", "EmployeeKey", OperationTypes.Delete),
        new DateTimeRule("DeletedDate", DateTimeKind.Local, OperationTypes.Delete)
        );
    Whenever a table is found with a soft delete column (DeletedFlag in this example), two things happen automatically:
    • All queries implicitly add “AND DeletedFlag = 0” to the WHERE clause.
    • All calls to DataSource.Delete become update statements to set the deleted flag.

    Entity Framework

    In Entity Framework, you can include an additional where clause on every query that reads from a table supporting soft deletes. You’ll also need to manually convert any delete operation into an update, which can be tricky when working with object graphs.
    Another option takes quite a bit of work, but may be less error prone. It starts by explicitly listing every table that supports soft deletes in the DataContext.OnModelCreating override.
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       modelBuilder.Entity<Employee>().Map(m => m.Requires("IsDeleted").HasValue(false));
    }
    You then need to override the Save method to ensure deletes become updates. Colin on Stackoverflow offers this pattern.
    public override int SaveChanges()
    {
       foreach (var entry in ChangeTracker.Entries()
                 .Where(p => p.State == EntityState.Deleted 
                 && p.Entity is ModelBase))
        SoftDelete(entry);
        return base.SaveChanges();
    }
    
    private void SoftDelete(DbEntityEntry entry)
    {
        var e = (ModelBase)entry.Entity;
        string tableName = GetTableName(e.GetType());
        Database.ExecuteSqlCommand(
                 String.Format("UPDATE {0} SET IsDeleted = 1 WHERE ID = @id", tableName)
                 , new SqlParameter("id", e.ID));
    
        //Marking it Detached prevents the hard delete
        entry.State = EntityState.Detached;
    }
    You’ll want to read the rest of Colin’s answer, as there are a lot of edge cases to be addressed.

    Access Logging

    While audit columns, history tables, and soft deletes cover all of the write scenarios, there are times when you also need to log reads. An example of this is the US health care industry. Any doctor or nurse needs the ability to access any patient’s medical records in the event of an emergency. But in the normal course of business, they are only legally allowed to do so when they are actively treating that patient.
    Since the records cannot be fully locked down, the next best thing is to track who is reading each record. This can be easily accomplished at the repository level by logging each query involving sensitive data. This is most easily done manually at the top of the relevant repository methods.

    Performance Logging

    When user experience is a feature, it is important to know how much time is being spent on a per-query basis. Merely tracking per-page performance isn’t enough, as one page may involve multiple queries. This is especially true of Entity Framework, as lazy-loading can hide database calls.

    Explicit Logging in the Repository

    Though it is tedious and easy to miss a query, one can simply wrap every query in a disposable timer. The pattern is as follows:
    public class OperationTimer : IDisposable
    {
        readonly object m_Context;
        readonly Stopwatch m_Timer;
    
        public OperationTimer(object context)
        {
            m_Context = context;
            m_Timer = Stopwatch.StartNew();
        }
        public void Dispose()
        {
            //Write to log here using timer and context
        }
    }
    And the usage:
    using(new OperationTimer("Load employees"))
    {
        //execute query here
    } 

    Chain

    Chain exposes a set of events at the data source level. The one needed in this case is DataSource.ExecutionFinished. Here is an example:
    static void DefaultDispatcher_ExecutionFinished(object sender, ExecutionEventArgs e)
    {
        Debug.WriteLine($"Execution finished: {e.ExecutionDetails.OperationName}. Duration: {e.Duration.Value.TotalSeconds.ToString("N3")} sec. Rows affected: {(e.RowsAffected != null ? e.RowsAffected.Value.ToString("N0") : "<NULL>")}.");
    }
    
    You can also attach a handler to DataSource.GlobalExecutionFinished, which listens to events from all data sources.

    Entity Framework

    The built-in logging capabilities of Entity Framework don’t make it possible to time individual queries. You can work around this limitation using a custom IDbCommandInterceptor.
    public class EFLoggerForTesting : IDbCommandInterceptor
    {
        static readonly ConcurrentDictionary<DbCommand, DateTime> m_StartTime = new ConcurrentDictionary<DbCommand, DateTime>();
    
        public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            Log(command, interceptionContext);
        }
    
        public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            Log(command, interceptionContext);
        }
    
        public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
            Log(command, interceptionContext);
        }
    
        private static void Log<T>(DbCommand command, DbCommandInterceptionContext<T> interceptionContext)
        {
            DateTime startTime;
            TimeSpan duration;
    
            m_StartTime.TryRemove(command, out startTime);
            if (startTime != default(DateTime))
            {
                duration = DateTime.Now - startTime;
            }
    else
                duration = TimeSpan.Zero;
    
            string message;
    
            var parameters = new StringBuilder();
            foreach (DbParameter param in command.Parameters)
            {
                parameters.AppendLine(param.ParameterName + " " + param.DbType + " = " + param.Value);
            }
    
            if (interceptionContext.Exception == null)
            {
                message = string.Format("Database call took {0} sec. RequestId {1} \r\nCommand:\r\n{2}", duration.TotalSeconds.ToString("N3"), requestId, parameters.ToString() + command.CommandText);
            }
            else
            {
                message = string.Format("EF Database call failed after {0} sec. RequestId {1} \r\nCommand:\r\n{2}\r\nError:{3} ", duration.TotalSeconds.ToString("N3"), requestId, parameters.ToString() + command.CommandText, interceptionContext.Exception);
            }
    
            Debug.WriteLine(message);
        }
    
    
        public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            OnStart(command);
        }
    
        public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            OnStart(command);
        }
    
        public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
            OnStart(command);
        }
    
        private static void OnStart(DbCommand command)
        {
            m_StartTime.TryAdd(command, DateTime.Now);
        }
    }
    This doesn’t offer a way to capture contextual data, but you can work around that limitation by shoving the context in ThreadLocal or AsyncLocal as appropriate.

    Permission Checks – Table Level

    While permission checks can be done at the application level, it is often advantageous to also enforce them in the repository. This eliminates the possibility the permission check is forgotten on newly created screens/pages.

    Repository Enforcement

    The simplest way to implement this is a role check at the beginning of each relevant function. For example,
    public int Insert(Employee employee)
            {
                if (!m_User.IsAdmin)
                    throw new SecurityException("Only admins may add employees");

    Database Enforced

    A more sophisticated option would involve creating multiple connection strings. When the repository is created, a connection string is selected based on the user’s role. In this case, the connection string for non-admin users wouldn’t have INSERT privileges on the employee table.
    Due to the complexity and maintenance headaches involved, this approach is not recommended except under very high security environments where multiple layers of defense are desired. Even then, it requires extensive automated testing to ensure every connection string has all the permissions it needs.

    Permission Checks – Column Level

    Permission checks may also be needed at the column level. For example, you may want to prevent users from giving themselves admin privileges. Or you may want to block non-managers from seeing employee salaries.

    Chain

    Chain leverages its audit rules capabilities to implement column level permission checks. An anonymous function is passed to the RestrictColumn constructor along with the column name and list of restricted operations. (A table name can be optionally specified as well.)
    var IsAdminCheck = user => ((User)user).IsAdmin;
    
    dataSource = dataSource.WithRules(
        new RestrictColumn("Users", "IsAdmin", OperationTypes.Insert|OperationTypes.Update, IsAdminCheck));
    To prevent reading of a restricted column, pass in the OperationTypes.Select flag.

    Dapper

    The easiest way to do this in Dapper is to simply have multiple SQL statements. If the user lacks a specific privilege, you simply select the SQL statement that omits those columns.

    Entity Framework

    For queries, there are a couple of options available.
    1. Manually create difference projections (i.e. Select clauses) depending on the user’s role
    2. Perform the query normally. Then if the permission check fails, loop through the result set, setting the restricted properties to null/0.
    For inserts, simply blank out the restricted properties as above.
    Updates are trickier. When restricting writes to individual columns, you cannot attach entities. Rather, you need to re-fetch the original record, copy across the permitted values, and then save that object instead of the one passed in by the application code. (Essentially our “novice” pattern from the previous article.)

    Mapping One Model to Multiple Tables

    An important concept in data architecture is the idea that you don’t need a one-to-one mapping between tables and classes. In order to make the database work more efficiently or to address a particular business rule, you will often find it advantageous to map one class to multiple tables.
    Say, for example, you were tracking baseball teams. You may have these tables:
    Table
    Primary Key
    Team
    TeamKey
    TeamSeasonMap
    TeamKey+SeasonKey

    If your application only understands the concept of a team in the context of a season, you may have one Team object that covers both tables.

    Chain

    In Chain, there isn’t a strong relationship between classes and tables. This means for updates you would write code such as this:
    dataSource.Update("Team", myTeam).Execute();
    dataSource.Update("TeamSeasonMap", myTeam).Execute();
    At runtime it will determine which properties are applicable to which tables and generate the SQL accordingly.
    Under this model, you would fetch the Team object from a view that joined both tables. (Chain doesn’t support joins directly and assumes they will always occur via views.)

    Entity Framework

    Entity Framework expects that multiple tables mapping to a single entity all share exactly the same primary key. This means that it will not support that scenario.
    • For reads, you can perform the join and projection using EF’s normal LINQ syntax.
    • For updates, you will need to copy the model into a separate entity for each table.

    Caching

    Generally speaking, caching is a repository concern. Since the repository knows when data is being altered, it is the best equipped to handle cache invalidation.

    Chain

    Caching is supported by Chain, but it needs to be applies on a query by query basis using appenders. Appenders are attached to operations before they are executed. In this case there are four appenders we care about:
    • .Cache(...)
    • .CacheAllItems(...)
    • .InvalidateCache(...)
    • .ReadOrCache(...)
    They are best explained by means of an example repository. Here you can see the interplay between caching individual records and caching collections using `CacheAllItems`.
    public class EmployeeCachingRepository
    {
    
        private const string TableName = "HR.Employee";
        private const string AllCacheKey = "HR.Employee ALL";
    
        public IClass1DataSource Source { get; private set; }
        public CachePolicy Policy { get; private set; }
    
        public EmployeeCachingRepository(IClass1DataSource source, CachePolicy policy = null)
        {
            Source = source;
            Policy = policy;
        }
    
        protected string CacheKey(int id)
        {
            return $"HR.Employee EmployeeKey={id}";
        }
    
        protected string CacheKey(Employee entity)
        {
            return CacheKey(entity.EmployeeKey.Value);
        }
    
        public Employee Get(int id)
        {
            return Source.GetByKey(TableName, id).ToObject<Employee>().ReadOrCache(CacheKey(id), policy: Policy).Execute();
        }
    
        public IList<Employee> GetAll()
        {
            return Source.From(TableName).ToCollection<Employee>().CacheAllItems((Employee x) => CacheKey(x), policy: Policy).ReadOrCache(AllCacheKey, policy: Policy).Execute();
        }
    
        public Employee Insert(Employee entity)
        {
            return Source.Insert(TableName, entity).ToObject<Employee>().InvalidateCache(AllCacheKey).Cache((Employee x) => CacheKey(x), policy: Policy).Execute();
        }
    
        public Employee Update(Employee entity)
        {
            return Source.Update(TableName, entity).ToObject<Employee>().Cache(CacheKey(entity)).InvalidateCache(AllCacheKey).Execute();
        }
    
        public void Delete(int id)
        {
            Source.DeleteByKey(TableName, id).InvalidateCache(CacheKey(id)).InvalidateCache(AllCacheKey).Execute();
        }
    }
    
    As you can see, Chain gives you a lot of control over your invalidation logic at the cost of having to carefully specify everything.

    Entity Framework

    Entity Framework has two levels of caching. The first level is limited to the data context and is primarily concerned with ensuring the object graph doesn’t have duplication entities that represent the same physical database record. Since this cache is destroyed along with the data context, it is not relevant to most caching scenarios.
    In EF terminology, what we’re looking for is known as a “second level cache”. While available in EF 5, version 6 of Entity Framework didn’t ship with any sort of caching out of the box. For this, you’ll need to turn to the third party libraries such as EntityFramework.Cache or EFSecondLevelCache. As you can see from these example libraries, there is no standard pattern for adding second level caching to EF.

    Free hosting web sites and features -2024

      Interesting  summary about hosting and their offers. I still host my web site https://talash.azurewebsites.net with zero cost on Azure as ...