Effortlessly query AI models (starting with Google's Gemini) and receive strongly-typed, structured C# objects as output. Instead of parsing messy JSON or string responses, define your desired C# class, and let the AI fill it in for you!
License
—
Deps
3
Install Size
—
Vulns
✓ 0
Published
May 13, 2025
$ dotnet add package AI.StructuredOutputEffortlessly query AI models (starting with Google's Gemini) and receive strongly-typed, structured C# objects as output. Instead of parsing messy JSON or string responses, define your desired C# class, and let the AI fill it in for you!
[Description] attributes on your class properties to guide the AI in populating the data.string, decimal, DateTime, enum, double, bool, etc.[Range] to provide further guidance to the AI.Install the package via NuGet Package Manager:
Install-Package YourPackageName
Or via the .NET CLI:
dotnet add package YourPackageName
(Remember to replace YourPackageName with your actual package name once published!)
In your Program.cs or startup configuration, add the Gemini structured output generator:
using AI.StructuredOutput; // Assuming this is your root namespace
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
public class Program
{
public static async Task Main(string[] args)
{
using IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
// Replace "YOUR_GEMINI_API_KEY" with your actual API key
services.AddGeminiStructuredOutputGenerator("YOUR_GEMINI_API_KEY");
})
.Build();
await host.StartAsync();
// ... your application logic
}
}
Important: Securely manage your API key. Consider using user secrets, environment variables, or a configuration provider for production applications.
Create a C# class that represents the structure you want the AI to populate. Use [Description] attributes to guide the AI on what each property means.
using System.ComponentModel;
using System.ComponentModel.DataAnnotations; // For [Range]
public class WheatherInfo // Renamed from WheatherInfo for correct spelling
{
[Description("The city and country, e.g., 'London, UK' or 'Paris, France'")]
public string Location { get; set; }
[Description("The current temperature in Fahrenheit")]
public decimal Fahrenheit { get; set; }
[Description("The current temperature in Celcius")]
public decimal Celcius { get; set; }
[Description("A very short, friendly greeting or a brief, light-hearted comment about the weather. For example: 'Enjoy the sunshine!' or 'Stay dry!' Do not make a joke, just say something like ´good morning´")] // Clarified instruction for AI
public string Joke { get; set; } // Consider renaming to `FriendlyMessage` or similar if "Joke" is misleading
[Description("The local date and time at the specified location when these weather conditions were recorded")]
public DateTime TimeStamp { get; set; }
[Description("The current wind conditions")]
public WindCondition WindCondition { get; set; }
[Description("Assign a random decimal number between 0.0 and 1.0 (inclusive)")]
[Range(0.0, 1.0)]
public double Test { get; set; } // Perhaps rename to `RandomValue` for clarity
}
public enum WindCondition
{
[Description("Calm, almost no wind")]
NoWind = 0,
[Description("A gentle breeze is present")]
LightWind = 1,
[Description("Noticeably windy, potentially strong gusts")]
StrongWind = 2,
}
Tip: The more descriptive your [Description] attributes are, the better the AI will understand what data to provide. You can also guide the format of the data.
Retrieve the IAiStructuredOutputGenerator service and use the AskAsync<T>() method:
// (Continuing from Program.cs Main method or another part of your application)
var service = host.Services.GetRequiredService<IAiStructuredOutputGenerator>();
string? city = null;
while (string.IsNullOrWhiteSpace(city))
{
Console.Write("Type a city to query the current weather: ");
city = Console.ReadLine();
}
Console.WriteLine($"Fetching weather for {city}...");
var weatherInfo = await service.AskAsync<WheatherInfo>($"What´s the weather like in {city}?");
if (weatherInfo == null)
{
Console.WriteLine("Oops, something went wrong. The AI couldn't provide structured data.");
}
else
{
Console.WriteLine($"--- Weather in {weatherInfo.Location} ({weatherInfo.TimeStamp}) ---");
Console.WriteLine($"Temperature: {weatherInfo.Celcius}°C / {weatherInfo.Fahrenheit}°F");
Console.WriteLine($"Wind: {weatherInfo.WindCondition}");
Console.WriteLine($"AI's friendly note: {weatherInfo.Joke}");
Console.WriteLine($"Random Test Number: {weatherInfo.Test}");
}
Console.Write("Press any key to close...");
Console.ReadKey();
Type a city to query the current weather: London
Fetching weather for London...
--- Weather in London, UK (2023-10-27 10:30:00) ---
Temperature: 12°C / 53.6°F
Wind: LightWind
AI's friendly note: Good morning!
Random Test Number: 0.734
Press any key to close...
(Note: Actual output will vary based on the AI's response.)
The SDK takes your C# class definition and uses the property names, types, and [Description] attributes to construct a schema or a set of instructions for the AI. It then sends your prompt along with these instructions to the configured AI model (e.g., Gemini). The AI attempts to generate a response that conforms to the requested structure, which the SDK then deserializes into an instance of your C# class.
services.AddGeminiStructuredOutputGenerator("YOUR_API_KEY").(Future providers can be added by implementing IAiStructuredOutputGenerator and providing a corresponding extension method.)
Free for all