C# 14 Is Here: Everything You Need to Know (With Code Examples)

Microsoft has shipped C# 14 alongside .NET 10, and it’s packed with quality-of-life improvements that make everyday code cleaner, safer, and more expressive. Let’s walk through every major feature โ€” with fresh, practical examples you can try right now.


1. Extension Members โ€” Properties, Statics, and Operators on Any Type

C# has long supported extension methods. C# 14 takes it much further with the new extension block โ€” you can now add properties, static members, and even operators to types you don’t own.

Imagine you work with strings a lot and want a clean .IsValidEmail check, a .WordCount property, and the ability to repeat a string with *:

public static class StringExtensions
{
extension(string text)
{
// Extension property โ€” use it like: email.IsValidEmail
public bool IsValidEmail => text.Contains('@') && text.Contains('.');
// Extension property โ€” use it like: sentence.WordCount
public int WordCount => text.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length;
}
extension(string)
{
// Static extension property โ€” use it like: string.Placeholder
public static string Placeholder => "N/A";
// User-defined operator โ€” use it like: "hello" * 3 => "hellohellohello"
public static string operator *(string text, int times) =>
string.Concat(Enumerable.Repeat(text, times));
}
}
// Usage:
string email = "dev@example.com";
Console.WriteLine(email.IsValidEmail); // True
Console.WriteLine("hello world".WordCount); // 2
Console.WriteLine(string.Placeholder); // N/A
Console.WriteLine("ping! " * 3); // ping! ping! ping!

This is a game-changer for library authors โ€” your APIs can now feel like true language primitives.


2. The field Keyword โ€” Say Goodbye to Backing Fields

Every C# developer has written a property with validation that forced them to declare a private backing field. The new field keyword lets the compiler generate it for you.

Here’s a UserProfile class that enforces age and username rules โ€” no manual backing fields needed:

public class UserProfile
{
// Compiler synthesizes the backing field automatically
public string Username
{
get;
set => field = string.IsNullOrWhiteSpace(value)
? throw new ArgumentException("Username cannot be blank.")
: value.Trim().ToLower();
}
public int Age
{
get;
set => field = (value is < 0 or > 150)
? throw new ArgumentOutOfRangeException(nameof(Age), "Age must be between 0 and 150.")
: value;
}
}
// Usage:
var profile = new UserProfile();
profile.Username = " Alice "; // stored as "alice"
profile.Age = 30; // fine
profile.Age = 200; // throws ArgumentOutOfRangeException

Cleaner classes, less noise โ€” and full control over validation logic without the ceremony.


3. Null-Conditional Assignment โ€” Assign Only When It Makes Sense

The ?. operator has been a null-safety staple for reading values. In C# 14, you can use it on the left side of an assignment too โ€” so the right side only executes when the target isn’t null.

Consider an e-commerce scenario where you conditionally update a shopping cart:

public class Cart
{
public string PromoCode { get; set; }
public List<string> Items { get; set; } = new();
public decimal Discount { get; set; }
}
Cart activeCart = GetActiveCart(); // might return null
// Old way โ€” manual null guard required:
if (activeCart != null)
{
activeCart.PromoCode = "SAVE20";
activeCart.Discount += 20m;
}
// C# 14 โ€” clean and concise:
activeCart?.PromoCode = "SAVE20";
activeCart?.Discount += 20m; // compound assignment works too!
// The promo code lookup won't even run if activeCart is null:
activeCart?.PromoCode = FetchBestPromoFromApi();

Notice the last line โ€” FetchBestPromoFromApi() is not called at all if activeCart is null. That’s a real benefit when those calls are expensive.


4. Implicit Span Conversions โ€” High-Performance Code, Less Friction

Span<T> and ReadOnlySpan<T> are the go-to tools for zero-allocation data processing in .NET. C# 14 introduces implicit conversions so you can pass arrays where spans are expected โ€” and vice versa โ€” without manual casting.

// A method that processes data efficiently using ReadOnlySpan
static double AverageTemperature(ReadOnlySpan<double> readings)
{
double sum = 0;
foreach (var temp in readings) sum += temp;
return sum / readings.Length;
}
double[] dailyReadings = { 22.5, 23.1, 21.8, 24.0, 22.9 };
// C# 14: the array converts implicitly โ€” no .AsSpan() call needed
double avg = AverageTemperature(dailyReadings);
Console.WriteLine($"Average: {avg:F1}ยฐC"); // Average: 22.9ยฐC
// Span and ReadOnlySpan also compose more naturally with generics
ReadOnlySpan<char> greeting = "Hello, World!";
Span<char> buffer = new char[greeting.Length];
greeting.CopyTo(buffer);

Less ceremony around high-performance code means it’s easier to adopt these patterns throughout your codebase.


5. nameof with Unbound Generics โ€” Cleaner Type Names

Previously, nameof required a closed generic type like nameof(Dictionary<string, int>) just to get back "Dictionary". In C# 14, you can pass the unbound form directly.

// Before C# 14 โ€” you had to supply dummy type arguments:
string name1 = nameof(Dictionary<string, int>); // "Dictionary"
string name2 = nameof(List<object>); // "List"
// C# 14 โ€” just use the unbound form:
string name3 = nameof(Dictionary<,>); // "Dictionary"
string name4 = nameof(List<>); // "List"
string name5 = nameof(Func<,,>); // "Func"
// Real-world use: building a generic cache key or log label
public static string CacheKey<T>() => $"cache:{nameof(List<>)}:{typeof(T).Name}";
Console.WriteLine(CacheKey<int>()); // cache:List:Int32
Console.WriteLine(CacheKey<string>()); // cache:List:String

6. Lambda Parameters with Modifiers โ€” No Full Types Required

When a lambda parameter needed a modifier like ref or out, you previously had to write the full type for every parameter, even the ones you didn’t care about. Not anymore.

// A delegate for a try-parse style conversion
delegate bool TryConvert<TIn, TOut>(TIn input, out TOut result);
// Before C# 14 โ€” all parameter types had to be spelled out:
TryConvert<string, int> parseOld = (string text, out int result) =>
int.TryParse(text, out result);
// C# 14 โ€” just add the modifier, skip the type:
TryConvert<string, int> parseInt = (text, out result) => int.TryParse(text, out result);
TryConvert<string, bool> parseBool = (text, out result) => bool.TryParse(text, out result);
// Works great for inline swap utilities with ref params:
delegate void Swapper<T>(ref T a, ref T b);
Swapper<int> swap = (ref a, ref b) => (a, b) = (b, a);
int x = 10, y = 20;
swap(ref x, ref y);
Console.WriteLine($"x={x}, y={y}"); // x=20, y=10

7. Partial Constructors and Events โ€” Better Source Generator Support

Source generators are a cornerstone of modern .NET tooling (think: EF Core, SignalR, logging). C# 14 extends the partial keyword to constructors and events, making generator-heavy classes much easier to split between generated and hand-written code.

// File: OrderProcessor.cs (your hand-written code)
public partial class OrderProcessor
{
// Defining declaration โ€” no body, no initializer
public partial OrderProcessor(string region);
public void Process(Order order) => Console.WriteLine($"Processing in {_region}");
}
// File: OrderProcessor.Generated.cs (source generator output)
public partial class OrderProcessor
{
private readonly string _region;
private readonly ILogger _logger;
// Implementing declaration โ€” has the body and base/this call
public partial OrderProcessor(string region) : base()
{
_region = region;
_logger = LoggerFactory.Create(b => b.AddConsole()).CreateLogger<OrderProcessor>();
_logger.LogInformation("OrderProcessor created for region: {Region}", region);
}
}

Your hand-written file stays clean and readable. The generated file handles all the plumbing. No mismatch, no duplication.


8. User-Defined Compound Assignment Operators

Custom types can now define their own behavior for compound operators like +=, -=, and *=. Previously this was inferred from the binary operator; now you can override it directly for full control.

public struct Budget
{
public decimal Amount { get; private set; }
public Budget(decimal amount) => Amount = amount;
// Standard addition
public static Budget operator +(Budget a, Budget b) => new(a.Amount + b.Amount);
// User-defined compound: += can now enforce a cap rule
public static Budget operator +=(Budget current, Budget extra)
{
var newAmount = current.Amount + extra.Amount;
return new Budget(Math.Min(newAmount, 100_000m)); // cap at 100k
}
public override string ToString() => $"${Amount:N0}";
}
var budget = new Budget(90_000m);
budget += new Budget(15_000m); // would be 105k โ€” capped to 100k
Console.WriteLine(budget); // $100,000

Getting Started with C# 14 Today

All of these features are available now. To try them out:

C# 14 continues the language team’s philosophy of removing friction without adding complexity. Each of these features solves a real daily annoyance โ€” and the cumulative effect on code readability is significant.

Source: What’s new in C# 14 โ€” Microsoft Learn

Your AI Coding Agent Can Now Build and Manage Dataverse โ€” Here’s How

The way enterprise software gets built is changing fast. Rather than manually piecing together APIs, command-line tools, and custom scripts, developers are increasingly turning to AI agents โ€” describing what they need and letting the agent figure out the execution. But for that shift to work with platforms like Microsoft Dataverse, the platform itself needs to be something agents can actually understand and operate.

That’s exactly what Dataverse Skills delivers. Released as an open-source plugin for GitHub Copilot and Claude Code, Dataverse Skills gives AI coding agents deep, practical knowledge of Dataverse โ€” from connecting and authenticating to building schemas, loading data, and running analytical queries. All of it driven by natural language.

What Are Dataverse Skills, Really?

At its core, Dataverse Skills is a plugin that teaches your coding agent how to work with Dataverse. It doesn’t expose a menu of commands for you to choose from. Instead, you describe your goal in plain English, and the agent decides which skills to apply, in what sequence, using which underlying tools.

Think of it as giving your AI agent a domain expert’s knowledge of Dataverse โ€” without you needing to be that expert yourself.

The underlying engine uses the Power Platform CLI (PAC CLI) for authentication, solution management, and automation tasks, paired with the Dataverse Web API and Python SDK for data operations. But you never have to think about any of that. Natural language is the only interface you need.

Three Phases, One Unified Experience

The plugin’s capabilities are organized around three core phases of any Dataverse project:

1. Connect

The agent discovers your Dataverse environments, authenticates using PAC CLI or Azure CLI, registers the Dataverse MCP server, and sets up a consistent project structure. You don’t configure anything manually โ€” the agent handles the entire discovery and initialization process.

2. Build

Once connected, the agent can scaffold full data models from scratch: tables, columns, choice fields, lookup relationships, many-to-many relationships, forms, and views. It picks the right tool for each task โ€” MCP for quick reads, the Python SDK for bulk operations, and the Web API as needed โ€” and registers every component into your solution automatically.

3. Operate

With the schema in place, the agent can load data, run cross-table analytical queries, and bulk-import records from CSV files. Need 50 realistic sample records with domain-specific content generated on the fly? One prompt is all it takes.

Seeing It in Action

Here’s a real example of what this looks like in practice. You open your terminal, install the plugin with a single command, and type:

“I’m building a logistics and inventory management system for Veloce Apparel. I need tables for Warehouses, Products, Suppliers, Shipments, and Incidents โ€” with lookups, a many-to-many between Products and Suppliers, and a self-referential shipment routing chain (tracking a package’s journey through hub transfers). Create everything in a VeloceLogistics solution, load sample data, and show me which shipments are currently delayed or stuck in transit.”

From that single prompt, the agent autonomously:

  1. Discovers your Dataverse environment and configures MCP
  2. Creates the solution using PAC CLI
  3. Builds five tables with choice columns, lookups, and a many-to-many relationship
  4. Generates and runs a Python script to bulk-load realistic sample data
  5. Queries across tables to answer the business question

No toggling between documentation tabs. No manual CLI commands. No context switching. The agent orchestrates everything from end to end.

Works With Both GitHub Copilot and Claude Code

Development teams rarely standardize on a single AI coding tool. Some developers prefer GitHub Copilot; others work with Claude Code. Dataverse Skills was built with this reality in mind. Since the skills are written as plain Markdown files with YAML frontmatter โ€” not compiled binaries or proprietary formats โ€” the same plugin works identically in both environments.

Install it from the plugin marketplace for either agent and you get the same knowledge, the same safety checks, and the same results. One investment, both tools covered.

Open Source and Built to Extend

The project is MIT-licensed and openly available on GitHub. Each skill is a standalone Markdown file โ€” readable, editable, and extensible without any compiled code. Teams can add new skills for their own Dataverse customizations, improve existing ones, or contribute bug fixes back via pull request. The architecture is deliberately approachable for anyone who wants to tailor it to their environment.

A Broader Shift in How Platforms Get Used

Dataverse Skills is more than a productivity tool โ€” it signals a broader direction for enterprise platforms. As AI agents become a standard part of the developer workflow, the platforms they interact with need to be operable through intent, not just through traditional interfaces. Describing what you want and having it built, configured, and queryable in your environment is no longer a future concept. With Dataverse Skills, it’s available today.

Getting Started

Install the plugin with one command:

  • GitHub Copilot (VS Code): /plugin install dataverse@awesome-copilot
  • Claude Code: /plugin install dataverse@claude-plugins-official

Then describe your intent and let the agent do the rest.

Original article: Dataverse Skills: Your Coding Agent Now Speaks Dataverse by Suyash Kshirsagar, Microsoft.

WSL Containers: A Game Changer for Linux on Windows

At Microsoft Build 2026, Microsoft introduced WSL containers โ€” a major evolution in Linux container development directly on Windows through the Windows Subsystem for Linux (WSL). Containers have become a cornerstone of modern development, from cloud-native applications and AI workloads to testing and deployment pipelines. WSL containers simplify this experience by providing a built-in, enterprise-ready way to create, run, and manage Linux containers on Windows, without requiring additional third-party tooling.

You can access the WSL container feature in the latest pre-release of WSL right away by running wsl --update --pre-release, or by downloading and installing it directly from GitHub.

Overview

WSL container adds two major new features to WSL:

  • A built-in Linux container CLI (wslc.exe)
  • An API for Windows applications to run Linux containers as part of their app logic

WSL Container CLI โ€“ wslc.exe

When you update to the latest WSL version, you get a new binary on your path: wslc.exe. This CLI tool supports full Linux container development workflows โ€” running, debugging, testing, and more โ€” with a familiar format that respects your existing muscle memory.

For example, you can run a full Linux desktop in a container:

wslc run -d --name=webtop -e PUID=1000 -e PGID=1000 -e TZ=Etc/UTC -p 3000:3000 -p 3001:3001 lscr.io/linuxserver/webtop:ubuntu-kde

Or check GPU access with a CUDA script:

wslc run --rm --gpus all pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0))"

There is also a built-in alias container.exe that maps to wslc.exe, so you can use either command interchangeably.

WSL Container API

Windows applications can now directly use containers as part of their application logic. WSL ships a NuGet package (available on nuget.org and the WSL releases page) with support for C, C++, and C#.

This API integrates with MSBuild and CMake, meaning you can add a few lines to your project files and have container build and deploy steps become part of your application’s build process โ€” no manual steps required. You can git clone and try a sample or check out the full API reference.

Integration with Enterprise Tools

Monitor Security Events with Microsoft Defender for Endpoint (MDE)

WSL’s existing MDE plugin has been updated to be aware of Linux container events, providing the same security coverage whether you are using a WSL distro or containers. This feature is currently available as part of a private preview which you can sign up for here.

Manage WSL Container Settings with Intune

New management settings for WSL container are being added, allowing organizations to:

  • Control whether users can use WSL distros or containers
  • Specify an allowlist of container registries for pulling images

This addresses the top customer ask: “How can I control which distros/Linux images are allowed in my organization?” Currently available via GPO and an ADMX policy, with official Intune dashboard support coming within a few weeks.

VS Code Dev Containers

WSLc support has been added to VS Code Dev Containers in version 0.462.0-pre-release. To set it up, open the VS Code Dev Container settings, find the “Docker Path” setting, and change it to wslc. This is currently in pre-release and will soon move to general availability.

Further WSL Improvements

Alongside the container feature, Microsoft is making significant improvements to the underlying technology powering both WSL and WSL container:

  • New default file system (virtiofs): Makes Windows file access 2x faster
  • New default networking mode (Consomme): Relays Linux network traffic through Windows, allowing Linux applications to benefit from the same networking environment, security policies, and enterprise integrations available to Windows applications
  • Improved memory reclaim techniques: Gradually and consistently releases memory back to the Windows host when not in use

These lower-level platform changes will also benefit other container tools built on WSL, such as Docker Desktop, Podman Desktop, and Rancher Desktop.

Learn More

You can view the presentation from Build 2026 to learn more about the use cases and see demos. Additionally, visit the WSL container docs page for in-depth guides and sample code.

Feedback and What’s Next

This feature is currently in the pre-release version of WSL as a public preview. Microsoft aims to make WSL containers generally available in fall 2026. Install it, try it out, and file issues and feedback at the WSL GitHub page.

Source: Microsoft Dev Blogs โ€“ WSL container is now available for public preview by Craig Loewen, Senior Product Manager

Connect to Dynamics 365 CRM Online using a client ID and secret in a C# console app


1. Prerequisites

  • Install the Dynamics 365 SDK assemblies. You can install the necessary NuGet packages, such as:
  • Microsoft.CrmSdk.CoreAssemblies
  • Microsoft.CrmSdk.XrmTooling.CoreAssembly
  • Register your app in Azure Active Directory (AAD) to retrieve the client ID, client secret, and tenant ID.

2. Code Implementation

The following code demonstrates how to authenticate and interact with Dynamics 365 CRM using the CRM SDK:

using System;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Tooling.Connector;

class Program
{
    static void Main(string[] args)
    {
        string clientId = "Your_Client_ID";
        string clientSecret = "Your_Client_Secret";
        string tenantId = "Your_Tenant_ID";
        string crmUrl = "https://Your_CRM_Organization.crm.dynamics.com/";

        // Create connection string
        string connectionString = $@"
            AuthType=ClientSecret;
            ClientId={clientId};
            ClientSecret={clientSecret};
            TenantId={tenantId};
            Url={crmUrl};";

        // Establish connection
        CrmServiceClient serviceClient = new CrmServiceClient(connectionString);

        if (serviceClient.IsReady)
        {
            Console.WriteLine("Connected to CRM successfully!");

            // Example: Retrieve accounts
            IOrganizationService service = serviceClient.OrganizationServiceProxy;
            QueryExpression query = new QueryExpression("account")
            {
                ColumnSet = new ColumnSet("name", "accountnumber")
            };

            EntityCollection results = service.RetrieveMultiple(query);

            foreach (var entity in results.Entities)
            {
                Console.WriteLine($"Account Name: {entity.GetAttributeValue<string>("name")}, Account Number: {entity.GetAttributeValue<string>("accountnumber")}");
            }
        }
        else
        {
            Console.WriteLine($"Failed to connect: {serviceClient.LastCrmError}");
        }
    }
}

3. Explanation

  • Authentication: The connection string uses AAD authentication with the client ID, client secret, and tenant ID.
  • Connection: CrmServiceClient establishes a connection to Dynamics 365.
  • Query: The QueryExpression retrieves data from the CRM, such as accounts in this example.

Note : This article was created with assistance from AI and there could be mistakes / error

Oracle Database in Docker Container

visit the below url
https://container-registry.oracle.com/ords/ocr/ba/database/free

pull the latest image
docker pull container-registry.oracle.com/database/free:latest

Run the container using the image
docker run –name oracleexpressdev -p 1521:1521 -p 5500:5500 -e ORACLE_PWD=oracle@1234 -v D:\LocalDB\OracleExpress\Datafiles:/opt/oracle/oradata container-registry.oracle.com/database/free:latest
The following is the explanation of the parameters
docker run: This is the Docker command to create and start a new container.
–name oracleexpressdev: This sets the name of the container to oracleexpressdev.
p 1521:1521 -p 5500:5500: These parameters map ports on your host machine to ports in the container.
p 5500:5500 maps port 5500 on the host to port 5500 in the container. This port is used for Oracle Enterprise Manager.
e ORACLE_PWD=oracle1234: This sets an environment variable inside the container. ORACLE_PWD is the the Oracle Database SYS, SYSTEM and PDB_ADMIN password (default: auto generated)
v D:\LocalDB\OracleExpress\Datafiles:/opt/oracle/oradata: This mounts a volume from your host machine to the container.
/opt/oracle/oradata is the path inside the container.
This allows the Oracle database to persist data on your host machine.
container-registry.oracle.com/database/free:latest: This specifies the Docker image to use for the container.
In this case, it’s the latest version of the free Oracle database image from Oracle’s container registry.

after the command is run , i got an error , Password cannot be null .

This implies there is an issue with the password that we provided to run the container .In my case , i provided oracle@1234 . so the issue here was @ symbol seems it is not accepting the special character .

so i changed password
docker run –name oracleexpressdev -p 1521:1521 -p 5500:5500 -e ORACLE_PWD=oracle1234 -v D:\LocalDB\OracleExpress\Datafiles:/opt/oracle/oradata container-registry.oracle.com/database/free:latest

Now every thing was fine . If all fgoes well , it will do some back ground work
and finally gives


VS Code Workspace & few example use cases for customizing your VS Code workspace:

what is a VSCode Workspace ?

A VS Code workspace is a feature in Visual Studio Code that allows you to organize your projects, files, and settings in a cohesive environment. Workspaces can be as simple as a single folder containing your project files, or as complex as a multi-root workspace that includes multiple folders and projects.

Here are some key aspects of a VS Code workspace:

  1. Single Folder Workspace: The most basic form, where you open a single folder containing your project files.
  2. Multi-root Workspace: Allows you to work on multiple projects simultaneously by adding multiple folders to the same workspace.
  3. Workspace Settings: Customize settings specific to your workspace, such as editor preferences, extensions, and debugging configurations.
  4. Launch Configurations: Manage launch configurations for debugging your projects.
  5. Task Configurations: Define tasks for building, testing, and running your projects.

To get started with a workspace, you can simply open a folder in VS Code. For more complex setups, you can create a multi-root workspace by selecting “Add Folder to Workspace” from the File menu.

1. Workspace Settings

Use Case: Youโ€™re working on a Python project and want to enforce specific linting rules.
Solution: Configure workspace settings to enable pylint and set custom rules.

{
    "python.linting.pylintEnabled": true,
    "python.linting.pylintArgs": ["--max-line-length=100"]
}

2. Adding Extensions

Use Case: Youโ€™re developing a web app and need tools to streamline your workflow.
Solution: Install extensions like Live Server, ESLint, and Prettier.

{
    "recommendations": [
        "ritwickdey.liveserver",
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode"
    ]
}

3. Multi-root Workspaces

Use Case: You have frontend and backend projects that need to be worked on simultaneously.
Solution: Add both projects to a single workspace for easier navigation and management.

"folders": [
    {
        "path": "frontend"
    },
    {
        "path": "backend"
    }
]

4. Task Configurations

Use Case: You need to automate the build process for a Node.js application.
Solution: Create tasks to install dependencies and run the build script.

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Install Dependencies",
            "type": "npm",
            "script": "install",
            "group": "build"
        },
        {
            "label": "Build Project",
            "type": "npm",
            "script": "build",
            "group": "build"
        }
    ]
}

5. Launch Configurations

Use Case: Youโ€™re debugging a Python application and need to set breakpoints and environment variables.
Solution: Configure launch settings to run your application with necessary parameters.

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "env": {
                "FLASK_ENV": "development"
            }
        }
    ]
}

6. Custom Keybindings

Use Case: You frequently need to format your code and want a custom shortcut.
Solution: Create a custom keybinding for the format document action.

{
    "key": "ctrl+shift+f",
    "command": "editor.action.formatDocument"
}

7. Snippets

Use Case: You often use a specific code pattern for React components.
Solution: Create a snippet to insert the boilerplate code quickly.

"React Component": {
    "prefix": "rfc",
    "body": [
        "import React from 'react';",
        "",
        "const ${1:ComponentName} = () => {",
        "    return (",
        "        <div>",
        "            ${2:/* component code */}",
        "        </div>",
        "    );",
        "};",
        "",
        "export default ${1:ComponentName};"
    ],
    "description": "Create a React functional component"
}

8. Theme and Appearance

Use Case: You prefer a dark theme and custom icons for a better coding experience.
Solution: Change the color theme and icon theme.

{
    "workbench.colorTheme": "Dark+ (default dark)",
    "workbench.iconTheme": "vscode-icons"
}

These examples demonstrate how customizing your workspace can streamline your development process, improve efficiency, and create a more enjoyable coding environment. ๐ŸŒŸ

Do you have any specific customization in mind, or would you like more examples?

(This article was created with assistance from AI)

Create a Console app and run in a Container with Visual Studio 2022

I couldn’t find an article on this topic . so i thought i will put one .

Now there are many ways to interact with the container .You can do it with visual studio , Docker Desktop /terminal window
The following shows how to interact with the console app running in container using visual studio .
click the button shown below to open the terminal window .

It opens the power shell in the /app directory
cd in to the the directory that has the dll file .Fo e.g in this case it will be
cd /app/bin/Debug/net9.0/
dotnet <.dllfile>
Now you will be able to interact with it


Another way to do it is to build the image from the docker file generated by visual studio, as shown below

so try to open a separate terminal window to interact with the container .

here i built the image from the docker file visual studio generated and then started a container from it.using the following command
D:\LocalProjects\2024\DotNetConsoleApps\JuiceShop.Solution>docker buildx build -t juiceshop:v2 -f ./JuiceShop/Dockerfile .
The following is the output of theabove command

Once the above command is successful , it created a container image .

if you have installed docker desktop you could see this local image .

Now, to spin a container from the image , you can execute the following command in the terminal
docker run -it –name “zzzz” juiceshop:v2

if you don’t specify –name followed by container name (in this example zzzz) then docker gives an arbitrary name to the container.

Run the container
docker run -it –name “zzzz” juiceshop:v2
Hello please enter your name ?
Ethan Hunt
hello Ethan Hunt


Mount Local file on windows to a Docker container

Imagine you have a web application container that needs to access configuration settings stored in a file on your host system. This file might contain sensitive information like database credentials or API keys. Storing such sensitive data directly within the container image can lead to security risks, particularly when sharing the image. To mitigate this issue, Docker provides storage options that help bridge the gap between container isolation and your host machine’s data.

Docker offers two primary storage options for persisting data and sharing files between the host machine and containers: volumes and bind mounts.

Here we will use the bind mount

docker run -it --mount type=bind,source=d:\\MyFolder\\temp,target=/app/data wordcounterapp:latest -s /app/data/config

e.g The above is the example of a console app running in a container . It counts the words in a sentence . I ve put a sentence in a file on my d drive in windows and mounted it to container and passed the argument 

I have a windows 11 host machine so my example is the use case where i have file in my local machine in a directory called "temp" and i want to mount it to a container .so i will mount the content of the directory on my source system to the container file system.
so in the above command , the source is d:\\MyFolder\\temp
target is /app/data/config

Note: Please make sure that file path is correct and there is no spaces for source and target values. for e.g
the space shown below between cmdline argument and value will also give error

create a dev container using vscode and push it docker hub

The following article describes how to create dev containers using vscode and publish it to docker hub .

1. Install Prerequisites

  • Docker: Install Docker Desktop from here.
  • VS Code: Install Visual Studio Code from here.
  • Remote – Containers Extension: Install the Remote – Containers extension in VS Code. You can find it in the Extensions view in VS Code .

2. Create a Dev Container Configuration

  1. Open your project in VS Code.
  2. Press Ctrl+Shift+P (or Cmd+Shift+P on Mac) to open the Command Palette.
  3. Type and select Remote-Containers: Add Development Container Configuration Files.
  4. Choose a predefined container configuration that suits your project’s needs or customize your own.

This will create a .devcontainer folder with a devcontainer.json file in your project.

3. Customize devcontainer.json

Edit the devcontainer.json file to include any specific tools, extensions, or settings your project requires. Here’s an example:

4. Build and Open the Dev Container

  1. Reopen the Command Palette and select Remote-Containers: Reopen in Container.
  2. VS Code will rebuild the container and reopen your project inside it.

we could see the vs code opening the code in dev container

you can see that that the container has loaded and i am able to run the code from within the container

5. Push the Container to Docker Hub

we need to first make sure that we are authenticated successfully in the docker hub .so
First, log in to Docker Hub from your terminal using:

Then here i will use dev container CLI to build and publish images .

  1. Install DevContainer CLI using Node JS package manager npm as follows :

2. Build and Push the Container

devcontainer build --workspace-folder <path_to_your_workspace> --push true --image-name <your_dockerhub_username>/<your_image_name>:<version>

Replace <path_to_your_workspace>, <your_dockerhub_username>, <your_image_name>, and <version> with your actual values.
Note : This command need to be execute in the host file system not inside container

Here’s a breakdown of that command:

  • devcontainer build: This is the main command for building a development container. It’s part of the Dev Containers specification, which allows you to define your development environment as code.
  • --workspace-folder <my_repo>: This flag specifies the root folder of your workspace. Replace <my_repo> with the path to your repository. For example, if your repository is in a folder named project, you would use --workspace-folder project.
  • --push true: This flag indicates whether the built image should be pushed to a container registry. By setting it to true, the image will be pushed after the build.
  • --image-name <your_dockerhub_username>/<my_image_name>:<optional_image_version>: This flag specifies the name (and optionally the version) of the image. Replace <your_dockerhub_username> with the docker user name which you can find it once you login to docker.com under the profile .
    Replace <my_image_name> with the desired name for your image. You can also include an optional version tag by replacing <optional_image_version>. For example, myapp:latest.

for example , refer the above command
i am executing the devcontainer command from the root directory of my repo that contains .devcontainer folder which makes it easy . Hence you will see that i ve indicated a “.” (dot) after the –workspace-folder parameter switch .

Once i execute command , since you have already authenticated docker earlier it will push your image to the docker hub and if it is successful , you will get the following :

Connect to localdb\mssqllocaldb in visual studio Server Explorer

The following are the steps to connect LocalDB in Visual Studio,

  • To connect to LocalDB in Visual Studio, follow these steps
  • Open Visual Studio and go to the Server Explorer window.
  • Right-click Data Connections and select Add Connection.
  • In the Add Connection dialogue box, select Microsoft SQL Server as the data source.
  • In the Server Name box, type (localdb)\MSSQLLocalDB.
  • Select Windows Authentication as the authentication method.
  • Click Test Connection to verify that the connection is successful.
  • Click OK to close the dialogue box and save the connection.