Wednesday, 4 January 2023

Sessions and Caching In ASP.NET Core

 How To Use Sessions In ASP.NET Core

1- We need to install the stable version of “Microsoft.AspNetCore.Session” from the NuGet Package Manager. Then only we can access the session state in ASP.NET Core.

2- Now, open the ”Startup.cs” to configure the services.  we need to add the session service to the container so that we can add the services in the “ConfigureServices” function.

public void ConfigureServices(IServiceCollection services)  
{
    services.AddDistributedMemoryCache();  
    services.AddSession(options => {  
        options.IdleTimeout = TimeSpan.FromMinutes(1); //Set Time  
    });  
    services.AddMvc();  
}

3- Configure the HTTP Request Pipeline

Now, in the same class, we add “app.UseSession()” inside the “Configure” function so that it gets called by the runtime.

app.UseSession();

Now we are ok to use session in our application. See the below code for session.

public class HomeController : Controller  
{  
    const string SessionName = "_Name";  
    const string SessionAge = "_Age";  
    public IActionResult Index()  
    {  
        HttpContext.Session.SetString(SessionName, "Jarvik");  
        HttpContext.Session.SetInt32(SessionAge, 24);  
        return View();  
    }  

    public IActionResult About()  
    {  
        ViewBag.Name = HttpContext.Session.GetString(SessionName);  
        ViewBag.Age = HttpContext.Session.GetInt32(SessionAge);  
        ViewData["Message"] = "Asp.Net Core !!!.";  

        return View();  
    }  
}

Cache in ASP.NET Core

ASP.NET Core supports several different caches. The simplest cache is based on the IMemoryCache. IMemoryCache represents a cache stored in the memory of the web server. Apps running on a server farm (multiple servers) should ensure sessions are sticky when using the in-memory cache. Sticky sessions ensure that requests from a client all go to the same server. 

Non-sticky sessions in a web farm require a distributed cache to avoid cache consistency problems. 

The in-memory cache can store any object. The distributed cache interface is limited to byte[]. The in-memory and distributed cache store cache items as key-value pairs.

Types of Caching in Dotnet Core: 

The lowest level of caching in ASP.NET Core that we are going to discuss is the caching of data using IMemoryCache and IDistributedCache. These interfaces are the standard, in-built mechanisms for caching data in .NET Core. All other techniques that we discuss later in the article rely on IMemoryCache or IDistributedCache internally.

IMemoryCache: IMemoryCache is very similar to the System.Runtime.Caching.MemoryCache cache from .NET 4.

You can register IMemoryCache in ConfigureServices using:

services.AddMemoryCache();

//services.AddDistributedMemoryCache();
//services.AddResponseCaching();

Implementing MemoryCache in Code.

public class BlahService
{
    private const string BlahCacheKey = "blah-cache-key";
    private readonly IMemoryCache _cache;

    public BlahService(IMemoryCache cache, IDatabase db)
    {
        _cache = cache;
    }
   
    public async Task<IEnumerable<Blah>> GetBlahs()
    {
        blahs = await _db.getAll<Blah>(...);
        _cache.Set(BlahCacheKey, blahs, ...);
        return blahs;
    }
}

When saving to IMemoryCache, MemoryCacheEntryOptions provides you with many ways to expire cache content. 

//absolute expiration using TimeSpan
_cache.Set("key", item, TimeSpan.FromDays(1));

//absolute expiration using DateTime
_cache.Set("key", item, new DateTime(2020, 1, 1));

//sliding expiration (evict if not accessed for 7 days)
_cache.Set("key", item, new MemoryCacheEntryOptions
{
    SlidingExpiration = TimeSpan.FromDays(7)
});

Learn more about Memory Cache https://learn.microsoft.com

IDistributedCache A distributed cache is a cache shared by multiple app servers, typically maintained as an
external service to the app servers that access it. A distributed cache can improve the performance
and scalability of an ASP.NET Core app, especially when the app is hosted by a cloud service
or a server farm.
A distributed cache has several advantages over other caching scenarios where cached data is
stored on individual app servers.
When cached data is distributed, the data:
  1. Is coherent (consistent) across requests to multiple servers.
  2. Survives server restarts and app deployments.
  3. Doesn't use local memory.
Distributed cache configuration is implementation specific. This article describes how to configure
SQL Server and Redis distributed caches. Third party implementations are also available, such as
NCache (NCache on GitHub). Regardless of which implementation is selected, the app interacts with
the cache using the IDistributedCache interface.

Learn More about distributed cache


Continue Reading →

Tuesday, 3 January 2023

Var type In C#

 C# lets you declare local variables without giving them explicit types. It is possible with the help of the “var” type variable.

The “var” keyword is used to declare a var type variable. The var type variable can be used to store a simple .NET data type, a complex type, an anonymous type, or a user-defined type.

When we declare a variable as a var type, the variable's type is inferred from the initialization at compile time.

When to use var

  • Use of “var” is not recommended everywhere. The var was created to handle declarations when the type is not known, such as generic types, lamdas, and query expressions. If you already know the type of a variable, you must declare that explicitly. Remember, if you don’t declare a variable explicitly, the compiler must do extra work to determine the type. While the cost of this operation may not be significant, it’s just unnecessary burden on the compiler.
  • Don’t use var for simple local variable types that are known to you.
  • Use of var when you’re not sure what type of data will be stored in a variable.
  • Use in anonymous types and anonymous collections.
  • Use of var improves code readability. Use when class names are extremely long.
  • Imported unmanaged code types that doesn’t follow naming conventions.
Continue Reading →

Thursday, 24 November 2022

React Custom Hooks

 Hooks are reusable functions.

When you have component logic that needs to be used by multiple components, we can extract that logic to a custom Hook.

Custom Hooks start with "use". Example: useFetch.

Build a Hook

Suppose, we are fetching data in our Home component and displaying it. 

import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";

const Home = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/todos")
      .then((res) => res.json())
      .then((data) => setData(data));
 }, []);

  return (
    <>
      {data &&
        data.map((item) => {
          return <p key={item.id}>{item.title}</p>;
        })}
    </>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Home />);

The fetch logic may be needed in other components as well, so we will extract that into a custom Hook.

Move the fetch logic to a new file to be used as a custom Hook:

useFetch.js:

import { useState, useEffect } from "react";

const useFetch = (url) => {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(url)
      .then((res) => res.json())
      .then((data) => setData(data));
  }, [url]);

  return [data];
};

export default useFetch;

Index.js

import ReactDOM from "react-dom/client";
import useFetch from "./useFetch";

const Home = () => {
  const [data] = useFetch("https://jsonplaceholder.typicode.com/todos");

  return (
    <>
      {data &&
        data.map((item) => {
          return <p key={item.id}>{item.title}</p>;
        })}
    </>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Home />);

We have created a new file called useFetch.js containing a function called useFetch which contains all of the logic needed to fetch our data.

We removed the hard-coded URL and replaced it with a url variable that can be passed to the custom Hook.

Lastly, we are returning our data from our Hook.

In index.js, we are importing our useFetch Hook and utilizing it like any other Hook. This is where we pass in the URL to fetch data from.

Now we can reuse this custom Hook in any component to fetch data from any URL.

Continue Reading →

useMemo Hook ReactJS

 The React useMemo Hook returns a memoized value.

  • Think of memoization as caching a value so that it does not need to be recalculated.

The useMemo Hook only runs when one of its dependencies update.

This can improve performance.

Performance

The useMemo Hook can be used to keep expensive, resource intensive functions from needlessly running.

for example, we have an expensive function that runs on every render. 

A poor performing function. The expensiveCalculation function runs on every render:

import { useState } from "react";
import ReactDOM from "react-dom/client";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);
  const calculation = expensiveCalculation(count);

  const increment = () => {
    setCount((c) => c + 1);
  };
  const addTodo = () => {
    setTodos((t) => [...t, "New Todo"]);
  };

  return (
    <div>
      <div>
        <h2>My Todos</h2>
        {todos.map((todo, index) => {
          return <p key={index}>{todo}</p>;
        })}
        <button onClick={addTodo}>Add Todo</button>
      </div>
      <hr />
      <div>
        Count: {count}
        <button onClick={increment}>+</button>
        <h2>Expensive Calculation</h2>
        {calculation}
      </div>
    </div>
  );
};

const expensiveCalculation = (num) => {
  console.log("Calculating...");
  for (let i = 0; i < 1000000000; i++) {
    num += 1;
  }
  return num;
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

Use useMemo

To fix this performance issue, we can use the useMemo Hook to memoize the expensiveCalculation function. This will cause the function to only run when needed.

We can wrap the expensive function call with useMemo.

The useMemo Hook accepts a second parameter to declare dependencies. The expensive function will only run when its dependencies have changed.

In the following example, the expensive function will only run when count is changed and not when todo's are added.

import { useState, useMemo } from "react";
import ReactDOM from "react-dom/client";

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);
  const calculation = useMemo(() => expensiveCalculation(count), [count]);

  const increment = () => {
    setCount((c) => c + 1);
  };
  const addTodo = () => {
    setTodos((t) => [...t, "New Todo"]);
  };

  return (
    <div>
     ...
    </div>
  );
};

const expensiveCalculation = (num) => {
// Code goes here...
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);



Continue Reading →

useEffect hook in ReactJS

 useEffect(): It enables for performing the side effects in the functional components.

Some examples of side effects are: fetching data, directly updating the DOM, and timers.

useEffect accepts two arguments. The second argument is optional.

useEffect(<function>, <dependency>)

We should always include the second parameter which accepts an array. We can optionally pass dependencies to useEffect in this array.

1. No dependency passed:

useEffect(() => {
  //Runs on every render
});

2. An empty array:

useEffect(() => {
  //Runs only on the first render
}, []);

3. Props or state values:

useEffect(() => {
  //Runs on the first render
  //And any time any dependency value changes
}, [prop, state]);

Example Code: 

import Expenses from './component/expenses/Expenses';
import React,{useEffect, useState} from 'react';
import NewExpense from './component/newExpenses/NewExpense';

let _dummyExpense= [];

const App= ()=> {
    const [expenses, setExpense]= useState(_dummyExpense);

    function getExpenseData(){
        fetch('http://localhost:65257/API/Expense/').then(
            response=> {
                return response.json();
            }
        ).then(
            data=> {
                console.log(data);
                setExpense(data);
            }
        );
    }

    useEffect(()=> {getExpenseData();},[]);

    const addExpenseHandler= (expense)=>{
        fetch('http://localhost:65257/API/Expense/',{
            method:"Post",
            body:JSON.stringify(expense),
            headers:{'content-Type':'application/json'}
        }).then(
            response=> {
                getExpenseData();
            }
        );
    }

    return <div className="app-container">
        <h2>Parent App</h2>

        <NewExpense onAddExpense={addExpenseHandler}></NewExpense>
        <Expenses item={expenses}/>
    </div>
}

export default App;

Effect Cleanup

Some effects require cleanup to reduce memory leaks.

Timeouts, subscriptions, event listeners, and other effects that are no longer needed should be disposed.

Reference: https://reactjs.org/https://www.w3schools.com/

Continue Reading →

Saturday, 19 November 2022

React: Unidirectional data flow

 Unidirectional data flow is a technique that is mainly found in functional reactive programming. It is also known as one-way data flow, which means the data has one, and only one way to be transferred to other parts of the application. In essence, this means child components are not able to update the data that is coming from the parent component. In React, data coming from a parent is called props. Angular makes use of bi-directional binding in which the data flow takes place in both directions. React doesn’t support bi-directional binding to make sure you are following a clean data flow architecture. The major benefit of this approach is that data flows throughout your app in a single direction, giving you better control over it.

In terms of React it means:

  • state is passed to the view and to child components
  • actions are triggered by the view
  • actions can update the state
  • the state change is passed to the view and to child components

Note: The view is a result of the application state. State changes when actions happen. When actions happen, the state is updated.

One-way data binding provides us with some key advantages. Like:

  • Easier to debug, as we know what data is coming from where.
  • Less prone to errors, as we have more control over our data.
  • More efficient, as the library knows what the boundaries are of each part of the system.

In React, a state is always owned by one component. Any changes made by this state can only affect the components below it, i.e its children. Changing state on a component will never affect its parent or its siblings, only the children will be affected. This is the main reason that the state is often moved up in the component tree so that it can be shared between the components that need to access it.






Continue Reading →

Sunday, 13 November 2022

ES6 Spread Operator

The ES6 (ECMAScript 2015) spread operator is a powerful feature in JavaScript that allows you to expand or spread elements from an array or object into another array or object. It is represented by three consecutive dots (...). Here’s a breakdown of how it works and some common use cases:

1. Spreading Elements in Arrays

You can use the spread operator to spread elements of an existing array into a new array.

  const fruits = ['apple', 'banana', 'cherry'];
  const moreFruits = ['orange', ...fruits, 'mango'];
  console.log(moreFruits);
 
  // Output: ['orange', 'apple', 'banana', 'cherry', 'mango']

In this example, the ...fruits spreads out the elements of the fruits array into the moreFruits array.

2. Copying Arrays

The spread operator is often used to create a shallow copy of an array.

Example:

  const originalArray = [1, 2, 3];
  const copiedArray = [...originalArray];
  console.log(copiedArray);
 
  // Output: [1, 2, 3]

3. Spreading Elements in Function Calls

You can use the spread operator to pass elements of an array as individual arguments to a function.

Example:

  const numbers = [1, 2, 3];
  const sum = (a, b, c) => a + b + c;
  console.log(sum(...numbers));
 
  // Output: 6

Here, ...numbers spreads the array elements as individual arguments to the sum function.

4. Combining Arrays

You can use the spread operator to combine multiple arrays into one.

Example:

  const array1 = [1, 2];
  const array2 = [3, 4];
  const combinedArray = [...array1, ...array2];
  console.log(combinedArray);
  // Output: [1, 2, 3, 4]

5. Spreading Properties in Objects

The spread operator can also be used to spread properties from one object into another. This is especially useful for creating new objects based on existing ones.

Example:

  const person = { name: 'John', age: 30 };
  const job = { title: 'Developer', company: 'XYZ Corp' };
  const personWithJob = { ...person, ...job };
  console.log(personWithJob);
  // Output: { name: 'John', age: 30, title: 'Developer', company: 'XYZ Corp' }

6. Merging Objects

You can use the spread operator to merge objects, where properties from later objects will overwrite properties from earlier ones if they have the same key.

Example:

  const obj1 = { a: 1, b: 2 };
  const obj2 = { b: 3, c: 4 };
  const mergedObj = { ...obj1, ...obj2 };
  console.log(mergedObj); // Output: { a: 1, b: 3, c: 4 }

In this case, the value of b in obj2 overrides the value of b in obj1.

The spread operator is a versatile tool that simplifies many common programming tasks related to arrays and objects.


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# (55) CD (1) CI (2) CloudComputing (2) Coding (10) CQRS (1) CSS (2) Design_Pattern (7) DevOps (4) DI (3) Dotnet (10) DotnetCore (20) Entity Framework (5) ExpressJS (4) Html (4) IIS (1) Javascript (17) Jquery (8) jwtToken (4) Lamda (3) Linq (10) microservice (4) Mongodb (1) MVC (46) NodeJS (8) React (10) SDLC (1) Sql Server (32) SSIS (3) SSO (1) TypeScript (3) UI (1) UnitTest (2) WCF (14) Web Api (16) Web Service (1) XMl (1)

Dotnet Guru Archives