Wednesday 9 October 2024

Unsubscribe observable

How to Unsubscribe

Various ways to Unsubscribe

Use Async Pipe: Use Async pipe to subscribe to an observable, it automatically cleans up, when we destroy the component.

Use Unsubscribe(): Use Unsubscribe() method on the subscription. It will clean up all listeners and frees up the memory

To do that, first create a variable to store the subscription.

  obs: Subscription;

Assign the subscription to the obs variable

  this.obs = this.src.subscribe(value => {
    console.log("Received " + this.id);
  });

Call the unsubscribe() method in the ngOnDestroy method.

  ngOnDestroy() {
    this.obs.unsubscribe();
  }

When we destroy the component, the observable is unsubscribed and cleaned up.

Continue Reading →

Sunday 6 October 2024

Clean Architecture

What is Clean Architecture?

Clean Architecture is a design pattern that separates an application into different layers based on their responsibility.  It’s a way of organizing your code into independent, testable, and reusable components. 

It isolates the business logic of the application from external details such as user interfaces, databases, and frameworks.

The primary objective of Clean Architecture is to create a structure that makes it easy to manage and maintain an application as it grows and changes over time. It also makes it easy to add new features, fix bugs, and make changes to existing functionality without affecting the rest of the application.

Implementing Clean Architecture in ASP .NET Core Web API

To apply Clean Architecture, we can divide the application into four primary layers:

Domain Layer – The domain layer represents the application’s core business rules and entities. This is the innermost layer and should not have any external dependencies. It contains domain entities, value objects, and domain services.

Application Layer – The application layer sits just outside the domain layer and acts as an intermediary between the domain layer and other layers. In other words, it contains the use cases of the application and we expose the core business rules of the domain layer through the application layer. This layer depends just on the domain layer.

Infrastructure Layer – We implement all the external services like databases, file storage, emails, etc. in the infrastructure layer. It contains the implementations of the interfaces defined in the domain layer.

Presentation Layer – The presentation layer handles the user interactions and fetches data to the user interface. It contains the user interface components (e.g., MVC, API Controllers, Blazor components).

With Clean Architecture, the Domain and Application layers are at the center of the design. This is known as the Core of the system.

The Domain layer contains enterprise logic and types and the Application layer contains business logic and types. The difference is that enterprise logic could be shared across many systems, whereas the business logic will typically only be used within this system.

Implementing the Project Structure:

Creating the Core Layer:

  1. Define Entities and Use Cases.
  2. Create a folder named “Core.”
  3. Within this folder, classes for Entities such as “User.cs” or “Product.cs” are created.
  4. Create interfaces or abstract classes for Use Cases like “IUserService.cs”.

Creating the Application Layer:

  1. Implement Use Cases.
  2. Create a folder named “Application.”
  3. Implement Use Cases as classes that inherit from the interfaces defined in the Core layer.
  4. For example: “UserService.cs”.

Creating the Infrastructure Layer:

  1. Implement Interface Adapters.
  2. Create a folder named “Infrastructure.”
  3. Implement concrete classes for the interfaces defined in the Core layer.
  4. For example: “UserRepository.cs” for “IUserRepository”.

Project Structure


Benefits of Clean Architecture:

Maintainability: Easier to modify and extend the system.

Flexibility: Adapts to changing requirements with minimal impact on other components.

Scalability: Better suited for large, complex systems.

Reference

https://code-maze.com/ , 

https://positiwise.com/

https://www.macrix.eu/ ,

https://medium.com/


Continue Reading →

Saturday 5 October 2024

RESTful API

 RESTful API, or Representational State Transfer API, is a set of rules and conventions for building and interacting with web services.

Key Principles of RESTful APIs:

Statelessness: Each request from a client must contain all the information the server needs to fulfill that request. The server does not store any client context between requests.

HTTP Methods: RESTful APIs use standard HTTP methods to perform operations on resources: GET, PUT, POST, DELETE

Stateless Operations: Each operation on the resource should be independent of others, ensuring scalability and reliability.

Client-Server Separation: The client and server operate independently

Benefits:

Scalability: Stateless interactions can scale more easily.

Flexibility: Clients and servers can evolve independently.

Caching: HTTP protocols allow responses to be cached for performance.

Overall, RESTful APIs are widely used for their simplicity and effectiveness in enabling communication between web services and applications.

RESTful APIs can be secured using HTTPS encryption, authentication mechanisms, and authorization mechanisms.

Continue Reading →

Saturday 21 September 2024

Dependency injection in Angular

Understanding dependency injection

Two main roles exist in the DI system: dependency consumer and dependency provider.

Angular facilitates the interaction between dependency consumers and dependency providers using an abstraction called Injector.

When a dependency is requested, the injector checks its registry to see if there is an instance already available there. If not, a new instance is created and stored in the registry. Angular creates an application-wide injector (also known as "root" injector) during the application bootstrap process, as well as any other injectors as needed.

Providing dependency

Imagine there is a class called HeroService that needs to act as a dependency in a component.

The first step is to add the @Injectable decorator to show that the class can be injected.

  @Injectable()
  class HeroService {}

The next step is to make it available in the DI by providing it. A dependency can be provided in multiple places:

  • At the Component level, using the providers field of the @Component decorator. In this case the HeroService becomes available to all instances of this component and other components and directives used in the template.
    For example:

  @Component({
    standalone: true,
    selector: 'hero-list',
    template: '...',
    providers: [HeroService]
  })
  class HeroListComponent {}

        When you register a provider at the component level, you get a new instance of the service
        with each new instance of that component.

  • For NgModule based applications, use the providers field of the @NgModule decorator to provide a service or other Injectable available at the application level.

for example:

  export const appConfig: ApplicationConfig = {
    //List of providers that should be available to the root component and all its children.
        providers: [
          { provide: HeroService },
        ]
    };

Then, in main.ts:

  bootstrapApplication(AppComponent, appConfig)

ApplicationConfig: Set of config options available during the application bootstrap operation.

At the application root level, which allows injecting it into other classes in the application. This can be done by adding the providedIn: 'root' field to the @Injectable decorator:

  @Injectable({
    providedIn: 'root'
  })
  class HeroService {}

When you provide the service at the root level, Angular creates a single, shared instance of the HeroService and injects it into any class that asks for it. Registering the provider in the @Injectable metadata also allows Angular to optimize an app by removing the service from the compiled application if it isn't used, a process known as tree-shaking.

Injecting a dependency

The most common way to inject a dependency is to declare it in a class constructor. When Angular creates a new instance of a component, directive, or pipe class, it determines which services or other dependencies that class needs by looking at the constructor parameter types. For example, if the HeroListComponent needs the HeroService, the constructor can look like this:

  @Component({ … })
  class HeroListComponent {
    constructor(private service: HeroService) {}
  }

When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If a requested service instance doesn't yet exist, the injector creates one using the registered provider, and adds it to the injector before returning the service to Angular.

When all requested services have been resolved and returned, Angular can call the component's constructor with those services as arguments.

 How Dependency Injection & Resolution Works in Angular?

The Angular creates a hierarchical dependency injection system. It creates a hierarchical tree of Injectors. Each Injector gets their own copy of Angular Providers. Together these two form the core of the Angular dependency injection framework. 

Injector

The Angular creates an Injector instance for every Component, Directive, etc it loads. It also creates an injector instance for the Root Module and for every lazy loaded module. But eagerly loaded modules do not get their own injector but share the injector of the Root Module.

Injector Tree

Angular Creates not one but two injector trees. Module Injector tree & Element Injector tree.

Module Injector tree is for Modules (@NgModule). For Root Module & for every Lazy Loaded Module.

Element Injector tree is for DOM Elements like Components & Directives.

Module Injector Tree

Angular creates the ModuleInjector for the services to be provided at Module Levels.

Angular Creates the Module Injector tree when the Application starts.

At the top of the Module Injector tree, Angular creates an instance of Null Injector. The Null Injector always throws an error unless we decorate the dependency with the Optional decorator.

Under Null Injector Angular creates an instance of PlatformInjector. Platform Injector usually includes built-in providers like DomSanitize etc.



Dependency providers
  • Class providers: useClass : The useClass provider key lets you create and return a new instance of the specified class. You can use this type of provider to substitute an alternative implementation for a common or default class. The alternative implementation can, for example, implement a different strategy, extend the default class, or emulate the behavior of the real class in a test case. In the following example, the BetterLogger class would be instantiated when the Logger dependency is requested in a component or any other class.

      [{ provide: Logger, useClass: BetterLogger }]

  • Alias providers: useExisting
  • Factory providers: useFactory

Read more in detail https://www.tektutorialshub.com/angular/angular-dependency-injection/

https://www.tektutorialshub.com/https://www.tektutorialshub.com/

https://www.tektutorialshub.com/angular/angular-providers/


Continue Reading →

Trackby in ngFor Angular

  Angular Trackby option improves the Performance of the ngFor if the collection has a large no of items and keeps changing. This can significantly reduce the number of DOM manipulations required, especially in large lists.

Here's a brief overview of how to use trackBy:

Syntax

You can use trackBy by providing a function that returns a unique identifier for each item in the list. This function is typically defined in your component class.

Example

Suppose you have a list of items that you want to display:

// In your component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-item-list',
  template: `
    <ul>
      <li *ngFor="let item of items; trackBy: trackById">{{ item.name }}</li>
    </ul>
  `
})
export class ItemListComponent {
  items = [
    { id: 1, name: 'Item 1' },
    { id: 2, name: 'Item 2' },
    { id: 3, name: 'Item 3' }
  ];

  trackById(index: number, item: any): number {
    return item.id; // Return unique identifier
  }
}

How It Works

  1. Define a Unique Identifier: The trackById function returns the unique id of each item. This helps Angular track which items have changed.

  2. Use trackBy in *ngFor: Add trackBy: trackById to the *ngFor directive.

Benefits

  • Performance: By using trackBy, Angular can skip re-rendering items that haven’t changed, which improves performance, especially with large datasets.
  • Reduced Reconciliation: It minimizes the work done during change detection by only updating the items that have changed.

When to Use trackBy

You should consider using trackBy whenever you're rendering lists, particularly when:

  • The list is large.
  • The items in the list may change frequently.
  • You want to improve the performance of your application.

Using trackBy is a best practice in Angular for rendering lists efficiently.



Continue Reading →

EF Core Migrations

What is EF Core Migrations

In EF core we create or update data models in our code. We call this approach the Code First approach. As our app grows, we are going to make a lot of changes to our model. This will result in our database going out of sync with the model.

Hence we need to update the database as we make changes to the model. But making changes manually is error-prone. We can also create a fresh database from the model, but it will result in loss of data.

The EF Core migrations make it easier to push the changes to the database and also preserve the existing data in the database. It provides commands like add-migration, remove-migration to create & remove migrations. Once migrations are generated, we update the database using the update-database. We can also generate the migration script and execute it in the production server.

How to Create Ef Core Migrations

Let us create a new console application to see how migrations work in entity framework core. Name the app as EFCoreMigration.

First, We will create a model and context class. Then we use the Migrations commands to create migrations and then later update the database.

Install the Microsof.Entity FrameworkCore.SqlServer package, which in turn installs the Entity Framework Core package

Install-package Microsoft.EntityFrameworkCore.SqlServer

Models for Migration

Create the Models folder and create two class Product.cs and Vendor.cs as shown below

Context: Under the models folder create the context class EFContext, which inherits from DBContext as shown below

using Microsoft.EntityFrameworkCore;
 
namespace EFCoreMigration.Models
{
    public class EFContext : DbContext
    {
 
        private const string connectionString = "Server=(localdb)\\mssqllocaldb;Database=EFCoreMigration;Trusted_Connection=True;";
 
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(connectionString);
        }
 
        public DbSet<Product> Products { get; set; }
        public DbSet<Vendor> Vendors { get; set; }
    }
}

Preparing for Migration

Open the Package Manager and run the following command.

Install-Package Microsoft.EntityFrameworkCore.Tools

Installing the above package also installs the Microsoft.EntityFrameworkCore.Design package. This package actually contains the commands like add migrations, Update database, scaffold an existing database by reverse-engineering the schema of a database, etc

List of Migration Commands

add migration

Whenever you create or Modify the domain classes, then the first thing you need to do is to create a Migration. This is done by add-migration command (or by using dotnet EF migrations add command line)

Open the Package Console manager and run the command

add-migration "initial" 

Inspecting the Migration scripts

The add-migration command created three classes under the folder Migrations. One is the Migration class and the second one is the designer class & the last one is snapshot class.

The add-migration command generates this file when it is run for the first time. In the subsequent runs, it uses it to find out the changes to be made to the model. It then overwrites it so that it remains up to date.

Update database

The add-migration creates the migration package but does not create the database.

The update-database command is used to bring the database in sync with the latest migration or the migration name specified as the argument

Run the update-database as shown below

update-database  

Open the SQL Server and you will see that the tables Products & vendors are created in the Database. Also, note that the _EFMigrationsHistory table.

__EFMigrationsHistory

This table keeps track of the Migrations applied to the database. It contains two columns one is MigrationId and ProductVersion. MigrationId contains the Unique ID of the migration and ProductVersion is the version number of Entity Framework used.

The update-databasechecks if the database exists. If the table __EFMigrationsHistory does not exists then the update-database applies the migration from the beginning and then creates the __EFMigrationsHistory

If __EFMigrationsHistory already exists, then update-database checks the to see the last migration applied and then continues to apply the migrations from the last migrations to the latest. It then inserts latest migration id in the __EFMigrationsHistory table

Update-database never checks the database schema to verify whether it matches with the model. So if you accidentally delete the __EFMigrationsHistory table, alter or delete any other table or fields, the EF Core never reports an error. The error occurs only when the App is running and you query the altered/deleted table

Connection string for update-database

The update-database requires us to create the OnConfiguring() method in the context class and expects us to pass the correct connection string to the desired database provider. For example if you are using the Sql Server then you need to call the method UseSqlServer(ConnectionString)

That is because the update-database instantiates the Context class and executes the onConfiguring method so as to configure the context. It is unaware of how and where you have stored the connection string. And it does not have the access to Dependency injection container as it runs outside the project.

Reference: https://www.tektutorialshub.com/


Continue Reading →

Topics

ADFS (1) ADO .Net (1) Ajax (1) Angular (47) Angular Js (15) ASP .Net (14) Authentication (4) Azure (3) Breeze.js (1) C# (47) CD (1) CI (2) CloudComputing (2) Coding (8) CQRS (1) CSS (2) Design_Pattern (7) DevOps (4) DI (3) Dotnet (10) DotnetCore (17) Entity Framework (4) ExpressJS (4) Html (4) IIS (1) Javascript (17) Jquery (8) Lamda (3) Linq (10) microservice (3) Mongodb (1) MVC (46) NodeJS (8) React (10) SDLC (1) Sql Server (32) SSIS (3) SSO (1) TypeScript (3) UI (1) UnitTest (1) WCF (14) Web Api (16) Web Service (1) XMl (1)

Dotnet Guru Archives