Private Routes using VueJs

Quite often in your application, you could come across when certain pages/routes could be accessed by only authenticated users. And then there are other pages, which could be access be any one.

I tend to call them by private routes and public routes. Private Routes requires a certain condition to be met, for example, the user needs to be authenticated. We could also have additional conditions like the user needs to have a certain privilege. If the condition is not met, the user attempting to navigate to the private route needs to be redirected to a common route, usually in public route.

In VueJs, the Navigation guards allows you to intercept the navigations and conditionally evaluate whether or not to accept the redirection or cancel it. While there are multiple ways to intercept the navigation process, per-route, in-component, the easiest way would be to use the the Global Guards.

Global Before Guards

The beforeEach guard method is probably the most common approach to handle navigations. The method is called each time when a new navigation starts.

You could add the validation code in the beforeEach method to ensure only the validated users access the pages.

const router = new VueRouter({
  routes,
});

router.beforeEach((to, from, next) => {
   // Your validation logic goes here.
});


The beforeEach Method accepts 3 parameters.

  • to : The future Route
  • from : the current Route
  • next : a function that should be called to resolve the route successfully.

Real World Scenario

Let us consider a real world scenario. You have couple of routes in your application.

const routes = [
  {
    path: "/",
    name: "Default",
    component: Default
  },
  {
    path: "/login",
    name: "Login",
    component: Login
  },
  {
    path: "/dashboard",
    name: "Dashboard",
    component: Dashboard
  },
];

Ideally, you would like the Default and Login to be accessed by anyone. However, the Dashboard should be accessed only by authenticated users only.

We begin by including this very bit of logic in our route definition. We could use the meta tags for including additional information. Redefining our routes now,

const routes = [
  {
    path: "/",
    name: "Default",
    component: Default,
    meta: {
      requiresAuth: false,
    },
  },
  {
    path: "/login",
    name: "Login",
    component: Login,
    meta: {
      requiresAuth: false,
    },
  },
  {
    path: "/dashboard",
    name: "Dashboard",
    component: Dashboard,
    meta: {
      requiresAuth: true,
    },
  },
];

As you can observe, we have added a requiresAuth flag within the meta information of routes. With this in place, we could now alter our beforeEach code as following.

router.beforeEach((to, from, next) => {
  if (to.matched.some((record) => record.meta.requiresAuth)) {
    if (isAuthenticated()) {
      next();
    } else {
      next("/");
    }
  } else {
    next();
  }
});

The method now checks if the to route has the meta information flag of requiresAuth set to true and if so, calls your custom isAuthenticated method to verify if the user is authenticated to access the page.

If the user is authenticated to access the page, the next() method is called to complete the navigation successfully. Otherwise, you override the to route and navigate away to a custom route, in this case using next(“/”).

That’s all your require for creating private routes using VueJs. If you would like to see the complete code, you could find the same here in my Github.

Evil Code #011 : Tuples

It has been long since I wrote a post in Evil Code series. So here is a short one, using the Tuples which was introduced in C# 7.X.

“introduced in C# 7.x” . You must be wondering why I used that phrase. Tuples was there before 7.x right ? Well, the answer is both yes and no. Tuples did exist before 7.x, but the one introduced in 7.x isn’t exactly the same. This newer version is a struct called System.ValueTuple and are noticeably different from its predecesoor in following ways.

  • System.ValueTuple is a struct, while System.Tuple is a reference type.
  • System.ValueTuple is mutable, while System.Tuple is not.
  • System.ValueTuple exposes items via Fields, while System.Tuple exposes items via properties.

You might have already seen a thousand articles on Tuples and have used them in your code base. So I would not go into further details on semantics and usages, but we will explore a special case.

Consider the following code.

var tuple1 = (Item1:1,Item2:2);
var tuple2 = (1,2);
var tuple3 = (Item2:2,Item1:1);

What would be the output of above code ?

Well, it would not even compile. The last would throw an error.

CS8125 Tuple element name 'Item2' is only allowed at position 2.
CS8125 Tuple element name 'Item1' is only allowed at position 1.

Why is it so ? Tuples can be broadly categorized in two ways – tuple literal and tuple types.

Tuple literals has a value and an optional name, while tuple typeshave type and optional name. In both cases, the name is optional and could be anything, except when the naming pattern uses the ItemN syntax.

These are reserved names which the tuple reserves for unnamed Tuple. You could use them as well, however, you are not allowed to alter the order.

Every element in the tuple could be accessed by the name if present, or its position. For acessing the Tuple element with position, .Net uses the naming convension ItemN where N is the position in the Tuple (1 based index).

The first element in the Tuple has to be Item1, the second Item2 and so on. If you alter the naming convention and use Item2 as the first element, the compiler would complain as shown above.

If you are attempting to name the first element as Item2, you are basically creating an ambiguity (should use the word confusion). This is why the naming convension prohibits such a pattern.

That was a rather a simple one right ? But that is the thing I like about the Evil Code series. Most of them are quite simple, but somewhere in the details, there are hidden facts which one as a developer needs to be aware of.

Real World Demo Applications

One of the recent projects I started on Github is NT – my own version of Thinkster’s Real World repos. The idea, much like the original idea, is to pick up a project topic and implement it in every language/framework i learn.

As a beginning, I have created the Web API using .Net 5 Preview with MongoDb as the database. The client is being currently developed under following platforms.

  • ReactJs
  • WPF

I also plan to the client implement with VueJs , Flutter/Dart and Xamarin in immediate future. Rest of the frameworks/languages would be added as and when I explore them. I am tempted to simultaneously implement the projects, rather than completing them sequentially due to personal reasons.

I am also making use of supporting frameworks like DocFx for documentations and Github Actions for CI/CD. The deployed documentation (generated with Docfx to begin with) would be deployed in Github Pages.

If you are interested in the project, please do follow it here in my Github.

Getting started with DocFx

I have been lately pretty impressed with the DocFx, Microsoft’s static documentation generator. In this blog post, I thought I would outline how easy it is to configure the DocFx for generating documentation for your project.

Assumption : Project already has Xml documentations enabled and the code have the necessary comments.

Step 1 : Install Chocolatey

  • Head over to Chocolatey’s official website and copy the command given in the getting started page.
  • Open the Powershell with Administrative prileges and executed the command copied.

For reference, the command is as follows.

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

Step 2 : Install Docfx

  • Install Doxfx with following command
cinst docfx -y

Step 3 : Generate DocFx Project

  • Generate Sample DocFx Project for your Project Documentation with the following command.
docfx init -q

Or if you would like to dictate the name for your project.

docfx init -q -o <DocumentationProjectName>

This would generate sample project for your purpose.

Step 4: Specify Project Details

The next step is to specify the location of your Project Files. This has to be mentioned in the docfx.json file.

I am including only the relavant part of docfx.json.

"src": [
        {
          "files": "src/infrastructure/Nt.Infrastructure.UI/**.csproj",
          "cwd": "..",
          "src": "../.."
        }

As you can observe, we have used base path using the src and cwd values, and use the files to specify the projects under consideration.

Step 5 : Build and Generate your documentation website.

That’s all the configuration you would need. Rest of the magic would be done by Docfx for you. To build the project and generate the website, you need to use the following command.

docfx --serve

And there you have it, you have your documentation up and running in the development server. You could access it via (http://localhost:8080/).

We will explore more features of DocFx and related configuration in later post, but surely, this would get you started.

Mocking User.Identity.Name

One of the other issue you might encounter while unit testing your Controller is when you dealing with Identity. Consider the following action method.

public async Task<BarResponse> Foo(BarRequest user)
{
    if (ModelState.IsValid)
    {
        try
        {
            var userName = User.Identity.Name;
            // Do Task
            return new BarResponse{
                
            };
        }
        catch (Exception ex)
        {
            return new BarResponse { ErrorMessage = ex.Message};
        }
    }
    else
    {
        var errrorMessages = ModelState.Values.SelectMany(x => x.Errors.Select(c => c.ErrorMessage));
        return new BarResponse { ErrorMessage = string.Join(Environment.NewLine, errrorMessages), modelState = ModelState };
    }
}

One of the issues is how do one mock the User.Identity.Name. The trick lies in creating a Test instance of DefaultHttpContext and replace with Controller’s context. Let’s write an Unit Test for the above code.

var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
{
    new Claim(ClaimTypes.Name, "anuviswan"),
    
}, "mock"));
userController.ControllerContext.HttpContext = new DefaultHttpContext() { User = user };

Guess what, I spend atleast 5 hours for figuring out this. Some of the harder days in life.

Writing Unit Test for Model Validation

It is a pretty common pattern to validate your Web Action model using ModelState.IsValid method. For example,

public async Task<UpdateUserProfileResponse> UpdateUser(UpdateUserProfileRequest user)
{
    if (ModelState.IsValid)
    {
        // Valid Model, do your job
    }
    else
    {
        // Send response indicating invalid model
    }
}

A pretty useful pattern, as it makes use of the DataAnnotations to validate and provide meaning messages. One question though that raises is, how do you unit test such a pattern ? The trick lies in emulating the ModelState. You could do with minimal code. For example,

protected void MockModelState<TModel,TController>(TModel model, TController controller) where TController: ControllerBase
{
    var validationContext = new System.ComponentModel.DataAnnotations.ValidationContext(model, null, null);
    var validationResults = new List<ValidationResult>();
    Validator.TryValidateObject(model, validationContext, validationResults, true);
    foreach (var validationResult in validationResults)
    {
        controller.ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage);
    }
}

With that in place, you could now write Unit Test for your controller as the following

var userController = new UserController(Mapper, mockUserProfileService.Object, null, null);
MockModelState(request,userController);
var result = await userController.UpdateUser(request);

That’s all you need.

Github Actions : Building your first workflow

Github Actions allows to create custom workflows to automate our development processes. In this series, we will walkthrough the creation of a workflow of a Web API which was build using .Net Core.

Do note that Github supports the developers using Custom templates, but since we are attempting to learng more on the Actions, let us build it from scratch.

Workflows

Workflows are automated process which could be triggered by actions such as a Push or Pull Request (among others), and could assist us to build, test, package, and deploy any projects. They are defined using the YAML Syntax.

You could create more than one workflow for your repository. All the workflow definitions must be stored under the .github/workflows repository.

Creating your first workflow

The first step required to create the workflow is of course, create the required definition file. So let us create our workflow definition file in the path .github/workflows/firstworkflow.yml.

  • Workflow Name

The first thing a workflow need is a name to identify it. Remember, we could have multiple workflows for the repository and it would be greatly helpful if we have some identifier to recognize the workflow. The workflow name could be stated using the name key in the first line of the workflow file.

name: Web API

  • What triggers the workflow

The second question that we need to answer is what triggers the workflow. The workflow requires a trigger action, this could be

  • Push to the repository
  • Pull Request
  • A Scheduled Event
  • An external event

For the starters, we will concentrate on the first two. We will address the Scheduled and external events later.

To begin with, let us assume, we need to trigger the workflow for every Push to the repository, irrespective of the branch. You could specify this by using the following.

# Workflow Name
name: Web API

# What triggers the workflow
on: push

Most often that not, you would like the workflows to be triggered only when a push has been done in the master branch. You could specify so by using the following.

# Workflow Name
name: Web API

# What triggers the workflow
on:
  push:
    branches: [master]

The above workflow would be triggered only when there is a Push to the master branch.The square brackets [] are used to signify a list. So if you would like to trigger the workflow in more than one branch, you could specify so by mentioning the branch name within the braces along with master.

In most development cycles, instead of a push, you would like to trigger the workflows only when a Pull Request is raised on master branch.

You could specify so by altering your workflow as

# Workflow Name
name: Web API

# What triggers the workflow
on:
  pull_request:
    branches: [master]

Now, the workflow would be triggered only on a Pull Request raised against the master branch.

  • Runner

Github supports a variety of Runners covering Linux, Windows and MacOS runners. Jobs are run on a fresh instances of a virtual machine.

You could choose the runner by using the runs-on key. For example,

runs-on: ubuntu-latest

The above code specifies that our code needs to be build on a latest version of Ubuntu runner.

You could also test across multiple operating systems using the build matrix. But let us explore that on a later day, as we focus on building a basic workflow action for our Web Api. Once we equipped with the basics, we could later customize the scripts for better efficiency.

  • Jobs

Jobs groups a set of steps that executes on the same runner. Workflows could have multiple Jobs and each job could be run seqeuentially or parrellely.

jobs:
  BuildWebApi:
    name: Build Web Api

  • Checkout

You have so far set the name of work flow, specified the event on which the workflow needs to be triggered and also mentioned the environment to run it on. But where is the code ?

The next step involve retrieving your code. This is done using the checkout action, a standard action provided by the Github community to retrieve your code.

Actions are individual tasks that you combine as steps to create a job. Actions are the smallest portable building block of a workflow. You can create your own actions, use actions shared from the GitHub community, and customize public actions. To use an action in a workflow, you must include it as a step.

Let us go ahead and check out the code using the checkout action.

- uses: actions/checkout@v2

More details of the checkout action could be found here.

  • Setup .Net Core.

Of course you need .Net Core in your Runner environment to build the application. We could use an action to set up .Net Core in your runner.

- name: Setup .NET 5
  uses: actions/setup-dotnet@v1
  with:
    dotnet-version: 5.0.100-preview.6.20318.15

With the above, we have asked the setup-dotnet@v1 action to install .Net 5 cli in the runner machine.

  • Build

Once you have the code and the environment, you are all set to build your code. You can use the dotnet build to build your solution.

- name: Build Web Api
  run: dotnet build --configuration Release

  • Execute Unit Tests

Just like the Build, you could use the dotnet test command to execute the unit tests.

- name: Execute Unit Tests
  run: dotnet test --no-restore --verbosity normal

  • Conditional Execution

Ideally, you could want to execute your Unit Tests only if your build has succeeded. You could achieve this with the Job Status Check Functions.

For example, the following would return true only when none of previous step has failed or cancelled.

if: ${{ success() }}

We could integrate it with our Unit Test execution as the following.

- name: Execute Unit Tests
  if: ${{ success() }}
  run: dotnet test --no-restore --verbosity normal

We have set up the our basic workflow for our Web Api. The complete workflow looks like following.

name: .NET Core

on:
  pull_request:
    branches: [master]

jobs:
  BuildWebApi:
    name: Build Web Api
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Setup .NET Core
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: 5.0.100-preview.6.20318.15
      - name: Build Web Api
        run: dotnet build --configuration Release
      - name: Execute Unit Tests
        if: ${{ success() }}
        run: dotnet test --no-restore --verbosity normal

That’s it for now, we will explore more on Git Actions in the later blogs. Have a great day.

Stay Open Functionality for Oxyplot Tracker

One of the recent questions on Stackoverflow was about having a Oxyplot tracker that

  • Is evoked only over the Points and NOT line/outside.
  • Stays Open until another point is selected.

The first part could be easily achieved by using a Custom PlotController that Binds the Mouse Down event only the Left Mouse Button and only on Tracks

CustomPlotController = new PlotController();
CustomPlotController.UnbindAll();
CustomPlotController.BindMouseDown(OxyMouseButton.Left, PlotCommands.PointsOnlyTrack);

You could now bind the CustomPlotController with your Xaml as

<oxy:PlotView Model="{Binding MyModel}" Controller="{Binding CustomPlotController}">

The second part needs you to write a Custom TrackerManipulator. The core idea would revolve around override the Completed method in TrackerManipulator, so that the Oxyplot is unable to hide the tracker.

If we were to ensure with the same TrackerManipulator that the trackers is enabled only Points, then the current tracker would be left open until the new tracker is opened at new location by a succeeding click on another point in the graph.

Let us go ahead and write our Custom TrackerManipulator.

public class StaysOpenTrackerManipulator : TrackerManipulator
{
    public StaysOpenTrackerManipulator(IPlotView plotView) : base(plotView)
    {
        Snap = true;
        PointsOnly = true;
    }
    public override void Completed(OxyMouseEventArgs e)
    {
        // Do nothing
    }
}

That’s all you need to achieve the goal. You can find the source code of this post in my¬†Github Repo

C# 9.0 : Top Level Programs and Targeted type ‘new’ Expression

In the previous post, we saw how C# 9.0 introduced the init only properties. In this blog post, we will explore some more of the language features which would be introduced in C# 9.0.

Top Level Programs

One of the annonying quality of any programming language is the baggage of boiler plate code that needs to be written for trying out a one-line. For example, prior to C# 9, even hello word looks like following.

using System;

namespace CSharp9.TopLevelPrograms
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

That is plenty of boiler plate code for a simple hello world program. There was hardly any improvements in this regard, with the exception of static directive which was introduced in C# 6.

using static System.Console;

namespace CSharp9.TopLevelPrograms
{
    class Program
    {
        static void Main(string[] args)
        {
            WriteLine("Hello World!");
        }
    }
}

Even with that, there were plenty of boiler plate code. All that comes to an end with the introduction of Top Level Program. Yo could no do away with explicit Main and other boiler plate codes. Starting with C# 9, you could rewrite the above code as

using System;
Console.WriteLine("Hello World");

Or including the static directive

using static System.Console;
WriteLine("Hello World");

If you are trying out a new language feature, this would be highly useful. No longer do you need to all those unncessary boiler plate codes. Behind the scenes, nothing has changed, it is the same old Main which the compiler has generated.

// $Program
using System;

private static void $Main(string[] args)
{
	Console.WriteLine("Hello World");
}

The Top Level Programs are not limited to above, you could also write methods and classes. The methods gets converted to local methods. For example,

using static System.Console;
WriteLine($"Hello {GetName()}");
WriteLine($"Hello {new Foo().GetName()}");

string GetName() => "Anu Viswan";
class Foo
{
    public string GetName() => "Anu Viswan";
}

The above code gets converted to

using System;
using System.Runtime.CompilerServices;

[CompilerGenerated]
internal static class $Program
{
	private static void $Main(string[] args)
	{
		Console.WriteLine("Hello " + GetName());
		Console.WriteLine("Hello " + new Foo().GetName());
		static string GetName()
		{
			return "Anu Viswan";
		}
	}
}
internal class Foo
{
	public string GetName()
	{
		return "Anu Viswan";
	}
}


As you can see, behind the scenes, the compiler does all the magic to create the regular code, but enables the developers to write sample codes within minimum code.

Targeted Type ‘new’ Expression

How often have you wondered _what if, what if the compiler could detect the targeted type, without the developer having the mention it explicitly`. For example, consider the following code

public class Foo
{
    public string FirstName { get; set; }
    public string Get(Bar bar) => bar.UserName;  
}

public class Bar
{
    public string UserName { get; set; }
}

// client code
Dictionary<string, string> dictionary = new Dictionary<string,string>
            {
                ["Name1"] = "Anu Viswan",
                ["Name2"] = "Jia Anu"
            };
Foo foo = new Foo{ FirstName = nameof(Foo.FirstName) };
foo.Get(new Bar{ UserName = nameof(Bar.UserName) });

If you observe the client code, you could be left wondering

  • Why do you need to the Dictionary Type explicitly defined on Right Hand side when the assigned type has been defined.
  • Same is the case with the type Foo on second line of client code.
  • Why not omit the type when you know the method expects the particular type in the last line ? The compiler already knows that the method Get() accepts a parameter type of Bar.

All these are now answered by in C# 9.0 with the Targeted Type new expression. For example, now you could skip the duplicate types and omit the types when the types could be infered.

The above code could be rewritten as

Dictionary<string, string> dictionary = new()
            {
                ["Name1"] = "Anu Viswan",
                ["Name2"] = "Jia Anu"
            };
Foo foo = new (){ FirstName = nameof(Foo.FirstName) };
foo.Get(new() { UserName = nameof(Bar.UserName) });

Now isn’t that better. I am more excited about the last line, where you could skip the Type name if it could be inferred.

We will continue our exploration of the language features in upcoming posts.

Evolution of Properties : C# 1 to C# 9

Properties in .Net has evolved over time, retaining its core functionality while making it super sleek via subtle changes. Let us take a brief look at the evolution before digging in deeper about the features introduced in C# 9.

C# 1.0.

Back when it all started, if you were to declare a property in C#, you needed to write a lot of boiler plate code. For example, if you were to create a class to represent a person, it could be like

public class Person
{
    public string _firstName;
    public string _lastName;

    public string FirstName
    {
        get
        {
            return _firstName;
        }
        set
        {
            _firstName = value;
        }
    }

    public string LastName
    {
        get
        {
            return _lastName;
        }
        set
        {
             _lastName = value;
        }

    }
}

That was a lot of boiler plate code for something so simple with no extranous validation or execution of arbitary code. You had to declare backing up fields and manually declare getters/setters for each of the property.

C# 2.0

C# 2.0 didn’t make the life much easier, but it provided a significant improvement. It allowed us to write different access modifiers for getter and setter. For example,

public string _firstName;
public string FirstName
{
    get
    {
        return _firstName;
    }
    private set
    {
        _firstName = value;
    }
}

C# 3.0.

C# 3.0 brought the first significant improvement in property declation with the introduction of auto implemented properties. Now you no longer needed to declare backing fields(of course you could do it as well if needed). The Person class declared in the preceeding example could be now modified as following.

public class Person
{
    public string FirstName{get;set;}
    public string LastName{get;set;}
}

Compare that with the code we wrote in C# 1.0 and we realize how much cleaner the code looks now. Of course the compiler would generate the backing up fields behind the scenes, but as a developer that was a lot of ‘less’ code to write.

However, there was a major caveat still. The Auto implemented property syntax was restricted to read-write properties. You weren’t allowed to use the auto-implemented properties in the case of readonly properties, at least not yet. For Read-only properties, you were forced to write the backing fields still.

We could of course use the private accessor for the setter, but that wasn’t exactly readonly property. It would only restrict another class from changing the property, but it never constrains the class to change it within itself. For example,

public class Person
{
    public string FirstName{get;private set;}

    public void Foo()
    {
        FirstName = "Hey I can change you here";
    }
}

In other words, if you intend to create a imutable property which could be set only in the constructor, this approach didn’t quite work.

C# 6.0

Another problem with the private setter approach is that the intend is not clearly indicated. However, this got a major boost in C# 6, which allow us to skip the setter in the declaration, and there by making the intend more clear.

public string FirstName {get;}

It also ensured that we could now write the much desired immutable property pretty easily and with more concise code. That isn’t all with the improvements in C# 6 for properties. There was other improvements which go a long way in improving our exprience as developer.

Prior to C# 6, if you wanted to initialize the value of a Auto Implemented Property, you were forced to do it within a constructor (if the constructor was implicit, you are forced to make it explicit). For example,

public class Foo
{
    public string FirstName { get; set; }
    public Foo()
    {
        FirstName = "Initial Value";
    }
}

That’s way too verbose. Why would on want to introduce an explicit constructor, when you could have done it at point of declaration. However, the developers were deprieved of this feature till C# 6.0. With C# 6.0 and above, you could now do,

public class Foo
{
    public string FirstName { get; set; } = "Initial Value";
}

That is a lot more concise code. C# 6.0 also introduced Expression Bodied Members, which could be applied to properties as well. For example, if you want to have a Readonly Age property, which needs to be calculated from DateOfBirth, you could do so,

public class Foo
{

    public DateTime DateOfBirth { get; set; }
    public int Age => DateTime.Now.Year - DateOfBirth.Year;

}

C# 9.0

Dispite the improvements made to the one of the most basic functionality, there was still something lacking. In C# 3.0, Object initializers were introduced, which enabled us a new way to initialize properties at time of creation. For example,

public class Foo
{
    public string FirstName{get;set;}
    public string LastName{get;set;}
}

var foo = new Foo{
    FirstName = "Anu",
    LastName = "Viswan"
};

This freed the author of the class from writing all sorts of constructor, which was an alternative till then. However, there was something amiss here.

If your property is a immutable property, you cannot use object initialier syntax to initialize the value during creation. You would have to depend on a lot of boiler plate constructors. For example,

public class Foo
{
    public string FirstName { get; set; }
    public string LastName { get; }
}

var bar = new Foo
{
    FirstName = "Anu",
    LastName = "Viswan" // This throws an error
};

This problem was resolved in C# 9 with introduction of init only properties. The C# language designers introduced the initaccessor which could be only used with the initializers. For example, the above scenario could be rewritten as

public class Foo
{
    public string FirstName { get; set; }
    public string LastName { get; init; }
}
var foo = new Foo
{
    FirstName = "Anu",
    LastName = "Viswan" // This works !!!
};

init accessor is a variant of set, which works only with object initializers. As you can see, this is a small change, but it fills a void that was irritating for the developers.

That’s it for now.