Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
150184 stories
·
33 followers

Aspire 13.2.0

1 Share

Aspire 13.2

Aspire 13.2 brings major CLI enhancements, a new TypeScript AppHost (preview), dashboard data export/import, Microsoft Foundry integration, and multi-language improvements — all focused on making local development more streamlined for developers and AI coding agents
alike.

Highlights

  • 🛠️ CLI overhaul — New commands including aspire start/stop/ps for detached mode, aspire describe for resource monitoring, aspire doctor for environment diagnostics, aspire secret for managing user secrets, aspire docs for browsing documentation from the terminal,
    and aspire agent (renamed from aspire mcp) for AI agent integration.
  • 🌐 TypeScript AppHost (preview) — Write your apphost in TypeScript with createBuilder(), using the same app model concepts as C#. Full VS Code extension support included.
  • 🧩 VS Code extension — Dedicated Aspire Activity Bar panel with live resource state, inline CodeLens with health status and actions, gutter decorations, and a new Getting Started walkthrough.
  • 📊 Dashboard improvements — Bulk telemetry export/import, export environment variables as .env files, a new telemetry HTTP API, set parameters directly from the dashboard, and improved resource graph layout.
  • 🤖 Microsoft Foundry — Replaces Azure AI Foundry integration with broader Aspire.Hosting.Foundry support including hosted agents and model deployments.
  • 🔒 Azure Virtual Network & Private Endpoints — New Aspire.Hosting.Azure.Network integration for defining VNets, subnets, NAT gateways, NSGs, and private endpoints directly in your apphost.
  • 🐳 Docker Compose publishing — Generate docker-compose.yaml from your app model with AddDockerComposeEnvironment.
  • 📦 New integrations — Azure Data Lake Storage, MongoDB EF Core (Aspire.MongoDB.EntityFrameworkCore), Bun support for JS resources, and Certbot for automated SSL certificates.
  • ⚡ App model — WithMcpServer for declaring MCP endpoints, rebuild command for project resources, contextual endpoint resolution, and improved secret/certificate handling.

⚠️ Breaking changes

Notable breaking changes include service discovery env vars now using endpoint scheme instead of name, aspire.config.json replacing split config files, AIFoundry → Foundry rename, WithSecretBuildArg → WithBuildSecret, and updated default Azure credential behavior.
See the full list of breaking changes.

📖 Learn more

For the full details on everything in this release, check out the What's new in Aspire 13.2 documentation.

Thank you to all the community contributors who helped make this release happen! 💜

Read the whole story
alvinashcraft
just a second ago
reply
Pennsylvania, USA
Share this story
Delete

Your Inbox As Options, Not Obligations

1 Share

I’ve heard this many times over the years:

… getting everything out of your head into a million projects and tasks feels like you are asked to do a little of everything.

https://bsky.app/profile/deejaygraham.bsky.social/post/3mfu3lh7oe22n

This leads to conclusions that I don’t share, such as “Getting Things Done pushes people towards multitasking [and I agree that multitasking is generally a mistake]”. I understand how reaching this conclusion can sour a person on Getting Things Done, but I see that conclusion as both a pity and avoidable.

The Apparent Moral Goodness of Never Saying “No”

You might have been conditioned to do (maybe literally) whatever people ask you to do. Some well-meaning adults might have taught you to do this when you were too young to question it. They taught you the virtues of helping, of being of service, of doing for others what you hope they would do for you when you needed it. Entire populations are taught the undeniable moral goodness of behaving this way. Religion aside, all this generally guides young people to become helpful, reliable members of society.

Sadly, it also risks teaching young people that they can’t say “No”. They grow up with a vague, unexplained, visceral, undeniable aversion to rejecting people’s requests to do things for them. They feel over-responsible for disappointing people, so they keep committing to more and more and more. And this becomes why they need a system such as Getting Things Done in the first place!

Folks struggling with Too Much To Do and Constantly Disappointing Everyone (Especially Themselves!) have a big, messy Inbox in their head: a master list of things they need to figure out when they’re going to do. Some of them also have some structure in their mind resembling Projects and Next Actions. Mostly, however, they have a jumble of too many tasks that they are constantly expediting and constantly forgetting and rediscovering. It feels really painful. It saps their energy. It sends them back to bed. Or worse.

Along comes Getting Things Done, which encourages them to start by bringing order to the chaos: write everything down and put it in The Inbox. Gather everything into The Inbox. Once you’ve got things safely in The Inbox, you can begin to figure out what you’ll do when, in what order: how you’ll manage to follow through on your commitments. It claims that this is a path to no longer having deadlines sneak up on them. It helps them stop letting important tasks fall through the cracks until they become urgent (and expensive!). It allows them to forget safely, so that they can focus on one thing at a time until, almost like magic, things are routinely getting done.

Sadly, it also risks freaking them out when they realize just how much they’ve committed to doing. And since The Universe keeps asking them to do things, they see The Inbox growing and growing and growing. The more they work The System, the farther behind they fall! They conclude that Getting Things Done hasn’t worked.

If you’re in this situation, or worried about this becoming your future, I have a proposal for you!

Options, Not Obligations

When you look at The Inbox and your Projects and Next Actions, what do you see? I suspect you see long lists of commitments, stretching as far as the eye can see. Commitments. Future Broken Promises. Obligations.

Guess what? You can choose.

It probably doesn’t feel like it, but you can choose. Over time, you can learn to see what’s in your Trusted System as options, not obligations. I suggest you start with The Inbox.

Detour: Software Development and Backlogs

In the world of software development, they talk often about Backlogs as a fundamental tool of planning. They have Product Backlogs (what we have to do in order to ship the product) and Iteration Backlogs (what we have to do in order to declare victory over the next 2 weeks or month). They probably have other kinds of Backlogs that they didn’t even read about in a book. These Backlogs are glorified, vaunted, revered, and feared shared “to do” lists. The details don’t matter much for this discussion, it might shock you to learn that these Backlogs are a source of significant confusion, debate, and dysfunction in the world of professional software development. I help clients with these problems. Many of those problems are problems of their own creation. (No shade; just facts. The struggle is real.)

Just like you and seeing The Inbox as frightening, painful obligations.

One big problem for software development professionals is that they see the Backlog as an immutable list of commitments. Once they put items in their various Backlogs, negotiation stops. They don’t adjust the plan to match emerging reality, such as workers quitting, getting sick, or going on vacation. Or learning that this key feature that we bet on is not going to sell. Or learning that that key feature is going to take 4 times as long to build as everyone thought, because technology. In professional software development, they cling to the misguided notion that they first plan, then they execute the plan, then they profit. In this environment, they turn Backlogs into immutable plans. Backlogs become constant reminders that they’ve bitten off more than they can chew. They feel like prisons.

Software development professionals use some of the tools of planning, but they forget to plan: to adjust their expectations as they encounter unpleasant surprises, to change their minds as they find out that their plan isn’t going to work, to react to the changing personnel and cash flows and market pressures.

This Is Not About Software Development

Maybe you do this, too. You intend to volunteer at your child’s school, but then you find out that it takes 3 times as much time and energy to do as you’d expected, and now you’re stuck. You tried to clean the garage last weekend, but once you started, you found out that it would cost way too much money to haul away all the stuff you wanted to donate and you didn’t have the heart to throw it all into a landfill, so you gave up. You keep staring at the piano, imagining how much fun it would be to play for an hour (or two!), but then you see the stack of papers on your desk and can’t justify the self-indulgence. And somehow you don’t take care of the papers, either. Who has the strength? I’ll watch a movie instead.

Stop the world. I want to get off!

Ceci N’est Pas Un Backlog

I propose you start here: The Inbox is Not a Backlog.

Instead of treating The Inbox like a list of commitments, treat it as a list of options: ideas, possibilities, things to reconsider later, idle thoughts to spend 10 minutes thinking more deeply about on Friday, potentialities… but not obligations. You need to make it safe in your own mind to put things in The Inbox without assuming that you actually have to do them!

I tell my software development clients to do this, but they often struggle, because there are many people in their project community, each with their own needs. They have competing objectives. They have differing philosophies. They care about different things. Any change to their working environment requires consent and getting that consent takes effort. Some people simply don’t feel ready to try to treat their Backlogs as anything less than obligations to do things under threat of losing their job. And, you know, their managers and executives routinely remind them about this threat every week!

You have an advantage: it’s just you in there! You can choose. You can experiment with making it safe to see The Inbox as options, not obligations. Nobody else can see inside your head. You can try and fail and try and fail and try fail until you suddenly succeed. Until you feel the click. Until you start seeing The Inbox as a collection of options, not obligations.

Feeling Safe in The Inbox

When you see The Inbox as options instead of obligations, it becomes safe to capture everything in The Inbox. You’re not going to do it all, anyway. You can’t. You don’t have enough time, energy, and money to do it all. You’re going to have more ideas and you need the freedom to sit and think about them. To mull them over, even when you’re not in the shower. You’re going to need to negotiate with The Universe regarding what you can reasonably commit to and what you can’t. You’re going to need to make room for doing things for yourself, because if you don’t, then you will run entirely out of energy and everything will stop! (We call this “burnout” and even “depression”.)

When you make The Inbox a safe place to capture every little idea, these big things happen:

  • You let yourself have ideas without fear of having to do anything with them. Your creativity kicks into high gear—or at least springs back to life.

  • You build a daily practise of scratching tasks off your list. You literally practise saying “No” to The Universe, but inside your own mind, where it’s safe because they can’t hear you and you don’t have face their disappointment. You can build confidence in your “No”, so that you can say it when you need to say it.

  • You focus more deeply and fully on the tasks you actually do, so you complete them sooner and with more energy. Sometimes you even have fun doing them!

  • You do more of the things you want to do and fewer of the things that you don’t. (No, really!)

  • You feel more confident in the commitments you keep, because you have increasingly clear evidence of what you can do and what you can’t do, of what you have space to do and what you don’t. You become the reliable, helpful person that those well-meaning (or maybe not) adults taught you to become.

As the saying goes, if you can’t say “No”, then your “Yes” means nothing. I prefer to say this:

Once you make peace with saying “No” to folks, you recapture the purest joy that comes from being able to say “Yes!” and meaning it.

And that starts with seeing The Inbox as full of options, not obligations. You can choose.

Getting Started

Spend 10 minutes with some paper and a pen and write all your uncompleted tasks (and projects) down. Just write. Write down anything you’re worried about forgetting. Don’t edit anything yet; just write. Write down the things you’ve always wanted to do, but never found time to do. Write it all down and don’t read any of it. Write down all the little things, too. The obvious things. The mundane, everyday things. Just write. This is The Inbox.

How do you feel now?

Once you have The Inbox, you can decide what to do with those items: scratch some off, put some deadlines or appointments on your calendar, set a reminder for Friday to spend 20 minutes thinking more about That Project You Maybe Want To Do, and then pick some things that you’ve already committed to, or that you want to get out of the way, or that you genuinely want to do today. (What? Meeting my own needs? In this economy?!)

Now put The Inbox away. You don’t ever have to look at it again, unless you want to spend more time processing it. Maybe what you’ve done now is enough to clarify what you need to today, for the rest of the week, and to begin next week. Maybe on Monday you can spend 10 minutes with some paper and pen and do this all again.

This is enough to get started. You’re doing Getting Things Done! It’s happening!

At some point, rewriting The inbox every Monday is going to become annoying. Or you might need to do it more often. Or less often. This means you’re ready for the next trick. Maybe then you have the energy to read the book. Or to come back here for the next trick. Or to send me a complaint or ask me a question, so that I can write about it.

Epilogue, or Future Work

Once you feel comfortable seeing The Inbox as options, not obligations, then you can imagine seeing your Projects and Next Actions as merely options, not obligations. (🤯?)

Related Reading

Gabor Maté, The Myth of Normal. Very young brains seem to behave a lot like adult brains in a hypnotic trance. If this is true, then you were literally hypnotized to believe what adults told you when you were a small child. This would explain why those Survival Rules seem automatic and impossible to ignore!

Read the whole story
alvinashcraft
48 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Coding Azure 23: Reading Settings from an App Configuration Service

1 Share

Today, we’ll get the code needed to retrieve the App Configuration service setting values in the application code.

In my last post, Coding Azure 22, I showed how to add settings to an App Configuration service to hold configuration information that needs to be shared among multiple components in a distributed application (the example I used was the name of a queue that would be written to by some frontend application and read from by some backend processor). In this post, I’ll look at the code you need to retrieve those setting values in your application code.

If you’ve worked with retrieving information from a .NET configuration file (e.g., the appsettings.json file in an ASP.NET Core application) through the IConfiguration interface, then you’re already familiar with most of what you need to do. It’s just a matter of integrating your App Configuration service into your configuration settings.

That means that you can treat your configuration file and your App Configuration service (and, if your application is running in an App Service, your App Service’s Environment Variables) as a single source.

Having said that, an App Configuration service provides a lot more options than a plain old JSON file or an Environments settings file. You may want to consider making an App Configuration service as your only source for configuration information.

Integrating Your App Configuration Service

To enable your application to access your App Configuration service, your application needs two NuGet packages:

  • Add Azure.Identity.Web (probably already part of your application’s dependencies)
  • Microsoft.Extensions.Configuration.AzureAppConfiguration

You’ll then need to update your application’s Program.cs file to integrate your App Configuration service into your application’s configuration information. Provided you have only one setting for any Key in your service, you just need to call the Configuration object’s AddAzureAppConfiguration, passing the URL for your service (as a Uri object) and some credential object. That could be as simple as this code:

builder.Configuration.AddAzureAppConfiguration(o =>
    o.Connect(new Uri("<url for your App Configuration Service>"), 
    new DefaultAzureCredential())   

You can retrieve the URL for your service from your App Configuration’s Overview page. Using DefaultAzureCredential will enable you to run your code from an App Service using the App Service’s Managed Identity and test your code from with Visual Studio or Visual Studio Code (assuming that you’ve added the Azure extension to Visual Studio Code).

Retrieving Setting Values

In an ASP.NET Core application, to retrieve a value from your merged configuration source, you must first retrieve the IConfiguration object from your application’s services collection. This example from an ASP.NET controller retrieves the service in the controller’s constructor and stores it in a field called config:

private readonly IConfiguration config;

 public Worker(ILogger<Worker> logger, IConfiguration config)
 {
     this.config = config;        

With the IConfiguration object in the config field, you could retrieve the value for a setting with its Key set to “QueueName” using this code:

string? qname = config["QueueName"];

In a Razor file you can retrieve the IConfiguration object using the inject directive. This code retrieves the IConfiguration object into a field called config and then uses it to retrieve a setting with a Key set to “AltText”:

@inject IConfiguration config
…
<img alt='@config ["AltText"]' …

Handling Duplicate Key Values

If the Key you specify doesn’t exist or there is more than one version of the Key, then both of those sets of code return null. (Because of that, it’s a good practice to always check for null after retrieving configuration values.)

You can have multiple versions of a Key if you’ve taken advantage of the App Configuration service’s ability to have multiple settings with the same Key, each with a different Label (e.g., “production,” “dev”). To avoid retrieving multiple versions of the same key, you’ll need to specify which version of any Key you want to retrieve when configuring your application.

In your Program.cs file, you can specify the version of each Key that you want by configuring AddAzureAppConfiguration through its options object, using the object’s Select method. The Select method accepts two parameters:

  • KeyFilter.Any
  • Either
    • LabelFiler.Null which matches to Labels that have no value
    • A string value to compare Labels to

You can use multiple Selects when configuring AddAzureAppConfiguration. Multiple Selects will not result in duplicate Keys because values retrieved by later Select methods overwrite values retrieved in earlier Selects.

The following example is typical code in a Program.cs in the production version of your application:

  • The first Select retrieves settings that don’t have a Label (i.e., settings that are to be used in any environment)
  • The second Select retrieves settings that have their Label set to “production”
builder.Configuration.AddAzureAppConfiguration(o =>
{
   o.Connect(new Uri("<url for your App Configuration Service>"), 
             new DefaultAzureCredential())
           .Select(KeyFilter.Any, LabelFilter.Null)
           .Select(KeyFilter.Any, "production");
});

Order matters here: If there is a Key that has both a version with no Label and a version with a Label set to "production,” the “production” version will overwrite the values from the version without a Label because the “production” version is selected second.

You can make this code more portable by replacing the hard-coded “production” string with a call to builder.Environment.EnvironmentName (provided, of course, that your environment names match the Labels you’re using in your App Configuration service). Be aware: Labels are case-sensitive: “Production” is not a match to “production.”

You have a different issue if Keys in your App Configuration file duplicate settings in either your application’s configuration file (e.g., appsettings.json) or in an App Service’s Environment Variables (all of which are merged into IConfiguration). Those matching keys form a hierarchy: App Configuration values override Environment Variables which, in turn, override configuration file settings. The danger here is that you may lose a setting in your configuration file because it’s accidentally overridden by a matching Key in your App Configuration service.

Handling Data Type

By default, all configuration values are treated as strings. You can use the config object’s GetValue method to handle conversions and, as a bonus, provide a default value.

The GetValue method is a generic method, which lets you specify the data type of the value you’re retrieving. You pass it the Key of the setting to retrieve and, optionally, a default value to return if the Key can’t be found or if the Key can’t be converted.

This example converts the setting’s value to an integer or returns -1 if the setting isn’t found or can’t be converted:

int? value = config.GetValue<int>("QueueLength", -1);

Retrieving Multiple Settings

If you used the recommended naming convention to group related Keys in your settings, then you retrieve those settings together. These sample Keys group together the WebServiceUrl and AuthorizationKey*n* settings by prefixing them with “SalesOrder”:

SalesOrder:WebServiceUrl
SalesOrder:AuthorizationKey1
SalesOrder:AuthorizationKey2

You can retrieve their values individually with code like this:

string url = config["SalesOrder:WebServiceUrl"];
string authKey = config["SalesOrder:AuthorizationKey1"];

However, you can also retrieve all the SalesOrder prefixed settings as a single group. You have two options here. One approach treats the SalesOrder settings as a class with properties; the other approach treats the SalesOrder settings as nested arrays.

Retrieving a Section as a Class

The first step in treating grouped settings as a class is to define a class with property names that match the members of the section (the class name doesn’t matter but the property names, while not case sensitive, must match the names of the child settings). A typical class for my SalesOrder settings might look like this:

internal class SalesOrderSection
{
   public string webServiceUrl {get; set;} = string.Empty;
   public string authorizationKey1 {get; set;} = string.Empty;
   public string authorizationKey2 {get; set;} = string.Empty;
}

Then, in your Program.cs file, as part of configuring your App Configuration service, you use the Configuration object’s GetSection method to retrieve the SalesOrder prefixed settings as a section. You then use the Services object’s Configure method to both load that section into your class and add that class to your application’s Services collection.

Typical code would look like this:

IConfiguration soSection = builder.Configuration
                                                                        .GetSection("SalesOrder");
builder.Services.Configure<SalesOrderSection>(soSection);

That code would create an IOptions<SalesOrderSection> object and add it to your application’s Services collection. The Value property of that IOptions object would hold the class with the SalesOrder section’s values.

Typical code in one of your application’s components to pull that object from the Services collection and retrieve the values stored in it would look like this:

private SalesOrderSection soSettings;

public HomeController(IOptions<SalesOrderSection> soSettings)
{
    this.soSettings = soSettings.Value;    
    string url = this.soSettings.webServiceUrl;

Retrieving a Section as an Array

Treating the SalesOrder prefixed settings as an array is more flexible but require more code. With this approach, instead of working in your Program.cs file, you use the IConfiguration object’s GetSection method in your application where you would retrieve individual values.

The GetSection method, when passed the prefix that defines your section returns an IConfigurationSection object. You then use that section object’s GetChildren method to convert all the settings in the section into an array of IConfigurationSection objects, each of which has a Key and a Value property (and a GetChildren method if your settings have their own nested settings).

This approach can be especially useful if your settings consist of repeated values because you can loop through the array without having to know how many repeated values there are.

This sample code loops through my SalesOrder settings looking for my Authorization keys:

IConfigurationSection secSO = config.GetSection("SalesOrder");
IEnumerable<IConfigurationSection> childrenSO = secSO.GetChildren();
string? key = string.Empty;

foreach (IConfigurationSection childSo in childrenSO)
{
    if ( childSO.Key.StartsWith("Auth")  )
    {
         key = childSO.Value;
       …process authorization key…
    }
}

Alternatively, you can use LINQ to retrieve specific values, as this example does by using the child object’s Key property:

string? value = childrenSO.FirstOrDefault(c => c.Key == "WebServiceUrl")?.Value;

Retrieving JSON Settings

If the value of your setting is a JSON document and you’ve set the Content type property of the setting to application/json, then you can treat the JSON document as if it were a section.

I could have, for example, created a setting with a Key set to “SalesOrder” and put this JSON document in it (which would also let me define my authorization keys as an array):

{
   "WebServiceUrl":"https://…",
   "AuthorizationKeys":   [
                                                    "a1…41",
                                                     "4b..ff"
                                                 ]
}

I can then retrieve individual values as if they were configuration settings in my service using code like this:

string? url = config["SalesOrder:url"]
string? authkey1 = config["SalesOrder:AuthorizationKeys:0"]
string? authkey2 = config["SalesOrder:AuthorizationKeys:1"]

You can also use the IConfigurationSection object with the GetSection and GetChildren methods to process your JSON document as I described earlier.

Retrieving Key Vault References

If you are using Key Vault references in your settings, you’ll need to configure your App Configuration’s service in your application’s Program.cs file to grant permission to access the vault at runtime.

The AddAzureAppConfiguration’s options object has a ConfigureKeyVault method that accepts an options object. You need to pass that options object’s SetCredential method the credentials that allow access to the Key Vault used in the Key Vault reference. Using DefaultAzureCredential will pick up your credentials in Visual Studio or Visual Studio Code for testing purposes and, at runtime, the Managed Identity assigned to the App Service hosting your application in the cloud.

This code would pick up the default credentials and use them for any Key Vault references:

builder.Configuration.AddAzureAppConfiguration(o =>
{
    o.ConfigureKeyVault(kvo =>
    {
        kvo.SetCredential(new DefaultAzureCredential());
    });
   o.Connect(});

You can then retrieve the unencrypted value from the Key Vault like any other setting just by using the setting’s Key like any other configuration setting:

string? value = config["AuthorizationKey"];

If you’re using multiple Key Vaults, the credentials you provide to the ConfigureKeyVault options object will be used for all the Key Vaults. If your Key Vaults require different credentials, you can use that options object’s SetSecretResolver method to specify different sets of credentials for different Key Vaults.

Retrieving Snapshots

If you’ve created an App Configuration snapshot to hold a collection of settings, you must configure the AddAzureAppConfiguration’s options object to select the snapshot you want to use. That’s done through the options object’s SelectSnapshot method, passing the Key for your Snapshot Reference setting (i.e., not the name of the snapshot itself). Be aware: If the snapshot can’t be found, no exception is raised.

Your snapshot’s settings are merged with the rest of your service’s settings. This can result in duplicate Keys (e.g., there’s a setting with a Key of “QueueName” in both your configuration settings and in the snapshot). If that happens, the last entry in the configuration settings list overrides any earlier settings, regardless of where the setting comes from.

This means that if you want to have your snapshot’s settings to always override your configuration settings then you should give your Snapshot References names that appear late in the alphabet (e.g., begin all your Snapshot reference Key values with “x-”).

Because snapshots are intended to provide a history of revisions made to your settings, you can not replace or edit a snapshot. However, you can change the snapshot used by a Snapshot Reference in your configuration. So, if you want to change the settings used by an existing Snapshot Reference in your configuration settings, then you must:

  1. Create a new snapshot
  2. Edit your Snapshot Reference to point to the new snapshot

Keeping Up to Date

With the code so far, if the value in a setting in your App Configuration service is changed while your application is running, your application won’t pick up the change.

If you want to keep your application using the current version of the settings in your App Configuration service (or, at least, one that isn’t very far out of date), then you should configure the service to refresh its values at some interval. You can do that by using the AddAzurAppConfiguration’s options object and calling its ConfigureRefresh method, passing a lambda expression that calls the SetCacheExpiration method (that method accepts a TimeSpan object).

The code for doing that is probably easier to understand than the explanation. Here’s some code that configures the configuration service to refresh its values every 10 minutes:

builder.Configuration.AddAzureAppConfiguration(o =>
{
o.ConfigureRefresh(ropt =>
        ropt.SetCacheExpiration(TimeSpan.FromMinutes(10)));

For this to be effective, though, in your code you must always retrieve your configuration values from the IConfiguration object. If, for example, you store a string value from the IConfiguration object in a field in your application, that field won’t be updated when your service is refreshed.

Handling More Complex Scenarios

If you find that you can’t do what you want by merging your App Configuration service into the rest of your configuration sources, you can create a ConfigurationClient object). The ConfigurationClient object provides methods for managing your App Configuration store, including adding and removing settings and snapshots.

More relevant to this post, the ConfigurationClient also provides GetConfigurationSetting and GetConfigurationSettingForSnapshot methods with multiple overloads that allow you to retrieve a value by any combination of Key, Label and date/time.

This code, for example, retrieves a complete setting by specifying both the Key and the Label:

ConfigurationClient cc = new(new Uri("https://whconfig.azconfig.io"),
                              new DefaultAzureCredential()); 
ConfigurationSetting cs = cc.GetConfigurationSettingAsync("QueueName", "production");

And that wraps up the App Configuration service! While App Configuration is essential for distributed applications, its integration with Key Vaults, its support Snapshots and its ability to be automatically refreshed all make it an attractive replacement, I think, for storing configuration information even for standalone applications.

Read the whole story
alvinashcraft
59 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Generative AI for Beginners .NET: Version 2 on .NET 10

1 Share

Today we’re releasing Version 2 of Generative AI for Beginners .NET, our free, open-source course for building AI-powered .NET applications.

If you want to understand and build generative AI applications, from core concepts to production-ready patterns, this is your starting point!

This new version restructured the entire curriculum into five focused lessons with full explanations, rebuilt everything on .NET 10, and moved to Microsoft.Extensions.AI as the primary abstraction.

If you went through v1, this is a different course.

Graphic for the announcement of Generative AI for Beginners .NET - Version 2

TL;DR

  • Completely rewritten curriculum with five structured lessons
  • All samples updated to .NET 10
  • New AI abstraction layer using Microsoft.Extensions.AI
  • Updated RAG implementations using native SDKs
  • New Microsoft Agent Framework lesson

Five lessons, fully rewritten

The biggest change in Version 2 is the course itself! We threw out the old lesson structure and rewrote everything from scratch into five lessons, each with complete explanations, working samples, and a clear learning arc.

  1. Introduction to Generative AI – What generative AI is, how large language models work, and how they connect to .NET, helping you understand the foundation for everything that follows.
  2. Generative AI Techniques – The practical core. Learn about chat completions, prompt engineering, function calling, RAG, reasoning, and structured outputs. Basically, write and understand AI code for real applications.
  3. AI Patterns and Applications – Taking the techniques from Lesson 2 and applying them to real application patterns. Learn how to apply generative AI techniques to real application architectures and production patterns.
  4. Agents with MAF – Multi-agent systems using the Microsoft Agent Framework. Tool use, orchestration, and how agents collaborate to solve complex tasks.
  5. Responsible AI – Safety, content filtering, evaluation, and the practices you need to ship AI features responsibly.

Version 2 goes deeper. Each lesson explains the concepts fully, walks through the code, and connects to the next lesson. You come out of it understanding not just how to call an API, but why the patterns work the way they do and how to apply them in real applications.

# Lesson Link Description
01 Introduction to Generative AI
  • What generative AI is and how it differs from traditional programming
  • Why .NET is a first-class citizen for AI development
  • The Microsoft AI stack and where each piece fits
  • How to run samples in GitHub Codespaces or configure local development
02 Generative AI Techniques
  • How to create chat conversations with context and memory
  • How text embeddings work and why they matter
  • How to process different content types including images and documents
  • How to call AI models using Microsoft.Extensions.AI abstractions
03 AI Patterns and Applications
  • How to build semantic search that understands meaning
  • How to implement retrieval augmented generation (RAG)
  • How to create applications that process and understand documents
  • When to use each pattern and how to combine them
04 AI Agents with Microsoft Agent Framework
  • What makes an agent different from a chatbot
  • How to build agents that use tools and take actions
  • How to orchestrate multiple agents working together
  • How to integrate with Model Context Protocol (MCP)
05 Responsible AI
  • How to identify and mitigate bias in AI applications
  • How to implement content safety and guardrails
  • How to build transparency and explainability into your systems
  • Ethical considerations specific to agentic systems

.NET 10 across the board

The samples now follow modern .NET patterns such as dependency injection, middleware pipelines, and file-based apps introduced in .NET 10. Authentication has also been standardized. All file-based samples now use AzureCliCredential, so you authenticate once through the Azure CLI and every sample picks it up. No more juggling connection strings or API keys across dozens of projects.

We also updated all model references to gpt-5-mini across the documentation and samples, reflecting the latest available models.

Microsoft.Extensions.AI as the foundation

Version 1 used Semantic Kernel as the primary way to talk to AI models. Version 2 uses Microsoft.Extensions.AI (MEAI).

The reasoning was straightforward. MEAI ships as part of the .NET 10 ecosystem, follows the same patterns as ILogger and IConfiguration, and works across providers without locking you into a specific orchestration framework.

In practice, this meant rewriting every core sample to use IChatClient and the MEAI middleware pipeline. The code got simpler. A basic chat completion that previously needed SK kernel setup, plugins, and connector configuration now looks like any other .NET service registration.

For example, the classic Space Invaders sample to learn how to integrate classic apps with AI!

RAG samples rewritten with native SDKs

We moved 11 pure Semantic Kernel samples to samples/deprecated/. They still build, they still work, and you can still reference them. But they’re no longer part of the main learning path.

For projects that mixed both SK and MEAI (like BasicChat-05AIFoundryModels and BasicChat-11FoundryClaude), we removed the SK dependency entirely and kept them running on pure MEAI.

We archived these samples because a beginner course should teach the foundational layer first, and in .NET 10, that layer is MEAI, and for agentic use, Microsoft Agent Framework is the premier toolkit to deploy and create agents.

Microsoft Agent Framework RC

Lesson 4 now covers the Microsoft Agent Framework, and we’ve documented it in the course materials! The five Microsoft Agent Framework web application samples continue to cover multi-agent orchestration, PDF ingestion, and chat middleware patterns.

Updated translations

All eight language translations (Chinese, French, Portuguese, Spanish, German, Japanese, Korean, Traditional Chinese) have been updated to reflect the new lesson structure, deprecation changes, and .NET 10 migration.

Getting started

Join the fun at Generative AI for Beginners – .NET!

Pick a provider (Microsoft Foundry or Ollama for local development), open Lesson 1, and work through the five lessons in order. Each one builds on the last.

If you run into issues or have suggestions, open an issue. If you want to contribute, PRs are welcome.

The post Generative AI for Beginners .NET: Version 2 on .NET 10 appeared first on .NET Blog.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

Announcing Aspire 13.2

1 Share

Aspire 13.2 is here — and this one’s a big deal.

TypeScript AppHost authoring. An AI-agent-native CLI. New and improved integrations. A smarter dashboard. We’ve been building toward some of these for a while, and today they ship.

Learn all about it at Aspire Conf happening TODAY. Watch live and hang out in the chat. We’ll be there.

Here are some of our favorite highlights. For the full breakdown, read the What’s New in 13.2.

🤖 A CLI built for coding agents

Coding agents need structure to build on and visibility into what’s happening. In 13.2, we focused on giving your agents the same power that Aspire gives you, so they can do complex work without you copy-pasting logs, manually restarting processes, and sending screenshots.

Whether you create a new Aspire sample app with aspire new or add an apphost to your existing codebase with aspire init, you’ll get Aspire specific skills and an MCP so your AI coding agents can work with you. Agents can start your AppHost in the background with the new --detach mode, stop and start any resource from the CLI without tearing down the whole system, and wait for resource statuses to update before moving on to their next action.

aspire run --detach
aspire resource api restart
aspire wait api --status healthy --timeout 120

The --isolated flag lets agents spin up parallel environments without stepping on each other — random ports, separate secrets, and no more conflicts across git worktrees.

The aspire docs command brings aspire.dev documentation directly into agent workflows so agents can search and retrieve docs programmatically without needed additional MCPs configured. Plus, aspire doctor validates your whole environment before an agent starts building.

And there’s more: first-class cert and secret management, aspire export for debug snapshots, and a unified aspire.config.json to simplify settings files.

CLI what’s new

TypeScript AppHost is here

This is the feature you’ve asked for the most since we shipped Aspire 13, and we’re excited to bring it to you in preview today. Now, you can write your Aspire AppHost in TypeScript. Full orchestration, dashboard, service discovery.

The CLI, VS Code extension, and dashboard all work exactly the same whether your AppHost is C# or TypeScript. And TypeScript is just the start — we built the multi-language foundation in a way that makes it repeatable, and more languages are coming in the near future!

Read more about TypeScript AppHost support

📊 Dashboard improvements

The dashboard now lets you export traces, spans, logs, and resource configurations as JSON or .env, and import telemetry bundles from aspire export to share debugging context with teammates.

Other highlights:

  • Improved GenAI visualizer with better schema handling and tool inspection
  • Adaptive force-directed resource graph layout
  • Persistent UI state for collapsed/expanded resources and filters
  • OTLP/JSON support alongside gRPC
  • Query string value masking for sensitive data
  • Consistent resource colors across dashboard and CLI

Read more about dashboard improvements

📦 New and improved integrations

What’s an Aspire release without more integrations? In 13.2, we added support for Certbot, overhauled the AI Foundry integration for the next-gen Microsoft Foundry, brought Bun into the JavaScript integration, and much more.

💫 Get started

aspire update --self
aspire update

New to Aspire? Head to get.aspire.dev to install and get started.

Want every detail? The full What’s New covers migration guides and all breaking changes.

Share feedback on GitHub, join us on Discord, X, or BlueSky.

As always, THANK YOU to our amazing community for your contributions, feedback, and motivation. Aspire is driven by and built for all of you 💖

Enjoy 13.2 – our favorite release yet. Happy Aspirifying! 💫

The post Announcing Aspire 13.2 appeared first on Aspire Blog.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

12 Years at the Microsoft MVP Summit: What Makes It Worth It

1 Share

I’m currently a 12-time recipient of the Microsoft MVP (Most Valuable Professional) award. The Microsoft MVP award is something Microsoft grants annually to individuals in the software community who are experts and actively share that expertise with the world. This can include speaking at conferences, writing, contributing to open source projects, and helping developers online, among other things.

Contrary to many people’s assumptions, it’s not something you just pay to get or a certification you earn once and keep forever. It’s awarded for only one year at a time, and you’re re-evaluated every year based on what you’ve done that year. You don’t just get it and keep it. You have to keep showing up and earning it.

Microsoft MVP Summit

This week I’ll be joining MVPs from all over the world at the Microsoft MVP Summit at Microsoft Headquarters in Redmond, Washington. If you’re not familiar with MVP Summit, it’s an invite-only event where Microsoft invites current MVPs to come on campus to meet with the Microsoft product teams that are building the platforms and tools we all use.

Almost everything that happens in those meetings is under NDA, which means Microsoft can be a lot more open with MVPs than they can in public settings. However, unlike real employees, MVPs work every day with Microsoft customers in the real world and have a valuable outside perspective that comes from that.

MVPs are not just watching from the audience, either. In most sessions we ask questions, push back, and share what we’re seeing in the real world. There aren’t many places where one can directly influence the direction of the tools they’re building with, but MVPs get that.

We also get a look at where things are heading. Not in a marketing sense, but in terms of technology direction, priorities, and the kinds of problems Microsoft is trying to solve next. That combination of seeing and shaping the future is pretty rare, and that’s a big part of why I love being an MVP.

So What

The obvious question is: what does any of that actually get you? For Trailhead’s clients, it comes down to two things — our ability to:

  • See where Microsoft is heading, and
  • Have a voice in shaping where things go

The seeing part matters because technology moves fast. When you’re choosing a platform, planning a migration, or deciding what to invest in next, you’re making a bet on where things will be in two or three years. Most people are making that bet based on what’s publicly available today. As an MVP, I get a broader perspective on the direction things are moving. I can’t share specifics that are under NDA, but that context absolutely sharpens the advice I give. There’s a real difference between reading the announcement blog post on the same day as everyone else and having the broader context to know which bets are safer than others.

The shaping part matters just as much. As consultants, the Trailhead team spends much of its time in the messy middle. Legacy systems, partial migrations, integrations. We see where things break in ways that sample apps and demos never reveal. The MVP Summit gives me a direct line to bring that back to the Microsoft teams building the tools, languages, and platforms. What’s working, what isn’t, and what our clients actually need.

That’s not something most consulting firms can offer. It’s not just that we know the Microsoft stack. It’s that we’re actively involved in the conversation about where it’s going next.

Why I Stay Involved

The recognition and MVP title itself is nice, but that’s not really why I stay involved. What I appreciate is the ability to see and shape the future of technology, and the expectations that come with it. If I want to stay an MVP, I need to work for it by staying up on what’s happening and sharing that with the software community. The same thing applies to my leadership in the .NET open source community through my board seat at the .NET Foundation.

So yeah, I’m looking forward to the MVP Summit this week. Not just because of big announcements or secret reveals, but because of the conversations that shape what comes next.

The post 12 Years at the Microsoft MVP Summit: What Makes It Worth It appeared first on Trailhead Technology Partners.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories