European ASP.NET 4.5 Hosting BLOG

BLOG about ASP.NET 4, ASP.NET 4.5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European ASP.NET Core 9.0 Hosting - HostForLIFE :: .NET Aspire Service Orchestration

clock April 14, 2025 08:15 by author Peter

The orchestration of.NET Aspire helps everything sing, from dispersed services to a coordinated symphony. We will delve deeper into orchestration using.NET Aspire in this chapter.

In this chapter, we will get deeper into orchestration with .NET Aspire.

  • Introduction to Orchestration in .NET Aspire.
  • Understanding the .NET Aspire Orchestrator.
  • Setting Up Your Aspire Orchestration Project.
  • Comparison with Docker Compose.

Introduction to Orchestration in .NET Aspire
As modern applications become more modular and distributed, orchestration becomes essential to tame the complexity. Whether it's a set of APIs, background workers, message queues, or third-party integrations, every moving part needs to be started, connected, and observed in a predictable way. That’s where .NET Aspire's orchestration capabilities shine.

Unlike traditional infrastructure-first orchestrators like Kubernetes, Aspire brings orchestration closer to the developer experience. It helps you declare and manage dependencies between projects and services within your solution, ensuring everything runs smoothly—without needing YAML or external tooling during development.

With Aspire, orchestration is,

  • Declarative: You define what services exist and how they relate to each other.
  • Integrated: It’s built right into the Aspire tooling—no need for Docker Compose or Kubernetes just to test things locally. Observable: Thanks to the built-in dashboard, you can monitor services, view logs, check health statuses, and trace failures all in one place.

The orchestration layer essentially acts as a central brain that boots up your projects in the right order, injects configuration and secrets, and ties everything together using environment variables and DI.

Understanding the .NET Aspire Orchestrator

At the heart of every .NET Aspire solution is a project typically named something like “YourApp.Orchestration”. This isn't just another project in your solution—it's the orchestration engine that wires up everything else.

Think of it as the composition root for your distributed application.

What Does the Orchestrator Do?
The orchestrator’s job is to,

  • Register services like your Web APIs, workers, Blazor apps, databases, caches, and even external services.
  • Configure dependencies between these services so they can talk to each other.
  • Inject environment variables and secrets automatically where needed.
  • Control the service startup order, ensuring dependencies are initialized in the right sequence.
  • Launch and monitor the services as a single unit during development.

Here’s a quick snippet showing how services are wired up inside the “Program.cs” of an Aspire Orchestrator project.
var builder = DistributedApplication.CreateBuilder(args);
var redis = builder.AddRedis("cache");
var productsApi = builder.AddProject<Projects.MyApp_ProductsApi>("products-api");
var frontend = builder.AddProject<Projects.MyApp_Blazor>("frontend");
builder.Build().Run();

This simple and intuitive code accomplishes quite a bit.

  • AddProject registers each project in your solution.
  • WithReference defines dependencies between services (injected as environment variables).
  • Services are automatically exposed via the Aspire Dashboard.

How Does Dependency Injection Work?
Aspire takes care of dependency wiring by exporting connection strings and configuration values as environment variables. For example, if your Products API needs Redis, Aspire will:

  • Automatically assign the Redis service a connection string.
  • Export it as ConnectionStrings__cache (or similar).
  • Your API can consume it using standard configuration binding in .NET.

What Services Can You Orchestrate?

  • ASP.NET Core APIs
  • Worker services
  • Blazor apps
  • Background jobs
  • Redis, PostgreSQL, SQL Server, MongoDB, RabbitMQ, etc.
  • External HTTP or gRPC endpoints.
  • Containerized services via AddContainer(...)

This makes it easy to emulate a realistic production environment locally, with minimal setup.

Setting Up Aspire Orchestration Project

If you are following me in this .NET Aspire quick guide, you must have prepared a blazor weather app in the last chapter, where we have added the support for resiliency using the .NET Aspire Service Default template;

To get started with service orchestration in your Aspire-powered solution, we first need to add an Aspire App Host Project.

  • Right-click the solution file in Solution Explorer.
  • Choose Add > New Project.
  • Search for .NET Aspire App Host and add it to your solution.

This project serves as the orchestration hub for your distributed application. In my example, I now have four projects in the solution, including the newly added project named BlazorWeatherApp.AppHost, following the standard Aspire naming convention.

Registering Projects with the App Host
Once the App Host project is added, the first step is to register all the required services — such as microservices, background workers, or frontend apps by referencing them inside the App Host project.


You can double-check the .csproj file of your App Host project to ensure all project references are correctly added.

What is the App Host and Why Use It?
In .NET Aspire, the App Host acts as the central coordinator for all services. It not only runs all your apps together but also provides features like.

  • Orchestration and centralized launching
  • Monitor all services
  • Built-in service discovery

Let’s look at the code to understand how services are registered.

What does builder.AddProject<>() do?
This method registers an application (like a microservice or a frontend project) with the App Host. It ensures.

  • The project is included in orchestration.
  • It’s monitored and tracked during execution.
  • It can discover and communicate with other registered services.

What role do these string parameters play here ("api", "myweatherapp")?
That string is the resource name or service identifier.

  • It's used for
    • Service discovery (e.g., resolving internal URLs)
    • Dashboard visualization (the names you see in Aspire Dashboard)
    • Logging and diagnostics labels
  • Think of it as a logical name for each project in the distributed system.

For example
builder.AddProject<Projects.BlazorWeatherApp_API>("api");

This means

  • Register the BlazorWeatherApp_API project
  • In service maps, configs, and communication, it's known as "api."

Setting App Host as Startup Project
Since the App Host handles orchestration, you no longer need to start multiple projects individually. Just set the App Host project as the startup project — it will launch and manage all other registered services automatically.

Run and Explore the Aspire Dashboard
After building the solution, run the App Host project. You’ll notice that a built-in dashboard UI launches with it.

On the Resources tab, you’ll see all your registered services listed — these are the ones added via the DistributedApplication.CreateBuilder() API.

This dashboard provides a single place to,

  • View the status of your services
  • Access service endpoints
  • Preview, test, or manage them in real time.

We’ll dive deeper into all the features of the Aspire Dashboard in the next chapter, but feel free to explore it now and get a feel for how Aspire centralizes the management of your distributed apps.

How .NET Aspire Orchestration Improves Manageability?
Orchestration isn't just about launching services—it's about taming complexity with structure, predictability, and control.

What Do We Mean by "Manageability"?
Manageability in this context refers to how easily a developer or team can,

  • Configure and run multi-service applications
  • Handle dependencies between services
  • Inject configuration (env vars, ports, secrets)
  • Maintain consistency across environments (local/dev/test)
  • Onboard new team members quickly

.NET Aspire Orchestration helps on all fronts
Comparing .NET Aspire Orchestration with Docker Compose
Docker Compose builds containers. Aspire builds confidence by making local orchestration feel like part of the codebase.

Why does This Comparison matter?
Both Docker Compose and .NET Aspire Orchestration aim to solve a similar problem:
“How do I spin up multiple dependent services locally in a predictable, repeatable way?”

But they approach it very differently.

Side-by-Side Breakdown

 

Feature Docker Compose .NET Aspire Orchestration
Setup Style YAML (declarative) C# code (imperative, type-safe)
Primary Use Case Dev/prod container orchestration Dev-time orchestration for .NET apps
Learning Curve Familiar to DevOps teams Friendly for .NET devs
Environment Setup Manual port/env config Automatic wiring + port/env injection
Telemetry Integration Requires manual OpenTelemetry setup Built-in with AddServiceDefaults()
Service Discovery Use of service names and ports Seamless via .WithReference()
Startup Order Management Controlled via depends_on Inferred through dependency references
Dashboard/Insights None (requires external tools) Built-in Aspire Dashboard
Production Readiness More production-aligned (with Docker/K8s) Dev-time only (not a prod orchestrator)
Tooling Integration Works across languages & stacks Tight integration with .NET ecosystem

DX (Developer Experience) with Docker Compose and Aspire

With Aspire (C#)

var redis = builder.AddRedis("cache");

var api = builder.AddProject<Projects.MyApp_Api>("api")
                 .WithReference(redis);

With Docker Compose (YAML)
services:
  redis:
    image: redis
    ports:
      - "6379:6379"
  api:
    build: ./api
    depends_on:
      - redis

Aspire gives you,

  • IntelliSense
  • Strong typing
  • Easier refactoring
  • Familiar project references

Where Docker Compose Still Shines?

  • Aspire is dev-time only, so for actual deployment scenarios, Docker Compose or Kubernetes is still necessary.
  • If you're working in a polyglot environment (e.g., Python + Node + .NET), Compose might still be the glue.
  • Aspire currently only supports orchestration of .NET projects and known service types (e.g., Redis, PostgreSQL, etc.).

What About Kubernetes?
Kubernetes is the heavyweight champion of production orchestration—but it’s overkill for your laptop.
While Kubernetes is the industry standard for production orchestration, it’s intentionally not used for local development in most cases. Here’s why

Kubernetes vs .NET Aspire Orchestration

 

Feature Kubernetes .NET Aspire Orchestration
Target Environment Production / Staging Local Development
Complexity High (requires YAML, Helm, CLI tooling) Low (C# code + dotnet run)
Startup Time Slower, may need Minikube / k3s Instant via .NET CLI
Learning Curve Steep for app devs Low, friendly for .NET developers
Tooling Integration External dashboards (Grafana, Prometheus) Built-in Aspire Dashboard

Takeaway

  • Use Kubernetes when deploying to the cloud at scale.

  • Use Docker Compose for multi-container, multi-stack local dev.

  • Use .NET Aspire Orchestration for pure .NET solutions where developer experience and manageability matter.




European ASP.NET Core 9.0 Hosting - HostForLIFE :: How to Use Blazor Server to Convert Images to Text (Easy OCR Example)?

clock April 11, 2025 08:49 by author Peter

First, make a Blazor Server application.
Launch Visual Studio and make a new project called Blazor Server App.


Install the necessary NuGet package in step two.
Install the Tesseract wrapper by opening the Package Manager Console.

Install-Package Tesseract

Step 3. Download Language Data

  • Go to Tesseract tessdata GitHub repo
  • Download eng. traineddata (for English)
  • Create a folder in your project named tessdata
  • Add the downloaded file to that folder
  • Set its properties: Copy to Output Directory → Copy if newer


Step 4. Download Language Data
@page "/"
@rendermode InteractiveServer
@using Tesseract
@inject IWebHostEnvironment Env

<PageTitle>Image OCR</PageTitle>

<h1>Image to Text (OCR)</h1>

<InputFile OnChange="HandleFileSelected" />
<br />
<button class="btn btn-primary mt-2" @onclick="ExtractTextFromImage">Extract Text</button>

@if (!string.IsNullOrEmpty(extractedText))
{
    <h3>Extracted Text:</h3>
    <pre>@extractedText</pre>
}

@code {
    private string? imagePath;
    private string? extractedText;

    async Task HandleFileSelected(InputFileChangeEventArgs e)
    {
        var file = e.File;
        var uploads = Path.Combine(Env.WebRootPath, "uploads");

        if (!Directory.Exists(uploads))
            Directory.CreateDirectory(uploads);

        imagePath = Path.Combine(uploads, file.Name);

        using var stream = File.Create(imagePath);
        await file.OpenReadStream().CopyToAsync(stream);
    }

    void ExtractTextFromImage()
    {
        if (string.IsNullOrWhiteSpace(imagePath))
            return;

        var tessDataPath = Path.Combine(Env.ContentRootPath, "tessdata");

        using var engine = new TesseractEngine(tessDataPath, "eng", EngineMode.Default);
        using var img = Pix.LoadFromFile(imagePath);
        using var page = engine.Process(img);

        extractedText = page.GetText();
    }
}

Step 5. Run the Application

  • Run your Blazor Server app.
  • Navigate to /ocr in the browser.
  • Upload an image file with text.
  • View the extracted text displayed below.


Original Image


Output



European ASP.NET Core 9.0 Hosting - HostForLIFE :: Understanding ASP.NET Core Web API Eager Loading

clock April 7, 2025 07:42 by author Peter

Consider that you are developing an application for a blog. When a user accesses your API to view their blog post, they anticipate seeing not only the content but also the comments, and possibly even the identity of each commenter. Now consider this:


Should I retrieve each component individually or should I make a single, effective request to the database?
You're considering eager loading if your instinct tells you, "One and done." Let's examine its definition, operation, and appropriate application in your ASP.NET Core Web API.

What Is Eager Loading?
Eager loading is a technique used with Entity Framework Core (EF Core) where you load related data alongside your main data in a single query. It's like ordering a combo meal instead of going back to the counter for fries and then again for your drink.

By using .Include() and .ThenInclude(), you’re telling EF Core:
Hey, while you’re grabbing that Blog, go ahead and pull in the Posts and their Comments too.

Why Use Eager Loading?

Here’s the deal

  • Performance boost: One query instead of many.
  • Avoid the N+1 problem: Imagine fetching 1 blog and 50 posts with separate queries—EF will hit the database 51 times!
  • Cleaner API results: Users don’t have to make extra requests to get the full picture.

Real-World Example. Blog, Posts, and Comments
Let’s build a sample project:
public class Blog
{
    public int BlogId { get; set; }
    public string Title { get; set; }
    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Content { get; set; }
    public int BlogId { get; set; }
    public Blog Blog { get; set; }
    public List<Comment> Comments { get; set; }
}

public class Comment
{
    public int CommentId { get; set; }
    public string Message { get; set; }
    public string AuthorName { get; set; }
    public int PostId { get; set; }
    public Post Post { get; set; }
}


This setup gives us:

  • A Blog with many Posts
  • Each Post with many Comments

DbContext Setup
public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
    public DbSet<Comment> Comments { get; set; }
}


Sample Seed Data
Let’s seed some mock data for testing:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>().HasData(new Blog { BlogId = 1, Title = "Tech with Jane" });

    modelBuilder.Entity<Post>().HasData(
        new Post { PostId = 1, Content = "ASP.NET Core is awesome!", BlogId = 1 },
        new Post { PostId = 2, Content = "Entity Framework Tips", BlogId = 1 }
    );

    modelBuilder.Entity<Comment>().HasData(
        new Comment { CommentId = 1, Message = "Loved it!", AuthorName = "John", PostId = 1 },
        new Comment { CommentId = 2, Message = "Very helpful!", AuthorName = "Alice", PostId = 1 },
        new Comment { CommentId = 3, Message = "Great explanation.", AuthorName = "Sara", PostId = 2 }
    );
}


Implementing Eager Loading in API
Here’s how to fetch a blog along with all its posts and the comments under each post:

[HttpGet("{id}")]
public async Task<IActionResult> GetBlogDetails(int id)
{
    var blog = await _context.Blogs
        .Include(b => b.Posts)
            .ThenInclude(p => p.Comments)
        .FirstOrDefaultAsync(b => b.BlogId == id);

    if (blog == null)
        return NotFound();

    return Ok(blog);
}


What’s happening here?
.Include(b => b.Posts) loads the Posts for the Blog.
.ThenInclude(p => p.Comments) loads the Comments for each Post.

All of this is done in one SQL query under the hood. No multiple round trips.

Best Practice. Use DTOs (Data Transfer Objects)
Returning full entities (especially with nested objects) is risky—you might expose internal or sensitive data. So, let’s clean it up using a DTO:
public class BlogDto
{
    public string Title { get; set; }
    public List<PostDto> Posts { get; set; }
}

public class PostDto
{
    public string Content { get; set; }
    public List<CommentDto> Comments { get; set; }
}

public class CommentDto
{
    public string Message { get; set; }
    public string AuthorName { get; set; }
}

Then in your controller
[HttpGet("{id}")]
public async Task<IActionResult> GetBlogDto(int id)
{
    var blog = await _context.Blogs
        .Where(b => b.BlogId == id)
        .Include(b => b.Posts)
            .ThenInclude(p => p.Comments)
        .Select(b => new BlogDto
        {
            Title = b.Title,
            Posts = b.Posts.Select(p => new PostDto
            {
                Content = p.Content,
                Comments = p.Comments.Select(c => new CommentDto
                {
                    Message = c.Message,
                    AuthorName = c.AuthorName
                }).ToList()
            }).ToList()
        })
        .FirstOrDefaultAsync();

    if (blog == null) return NotFound();
    return Ok(blog);
}


Now your API returns only what the client needs. Clean. Efficient. Secure.
Important Things to Remember

Use eager loading when

    You know you’ll need related data.
    You want to optimize performance with fewer database hits.

Avoid eager loading when

    The related data is huge, and you don’t need all of it.
    It slows down the response or affects performance negatively.

Output

 

Conclusion
The ASP.NET Core Web API's eager loading capability is a potent tool that enables you to effectively get relevant data using Entity Framework Core. by using leverage. Include() as well as. By using ThenInclude(), you may address the N+1 problem, get rid of pointless database searches, and enhance API speed. Eager loading must be used carefully, though; just include the information you require, and think about use DTOs to maintain secure and tidy answers. When used properly, eager loading facilitates the development of more scalable, well-organized, and quicker APIs.



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in