Chapter 7: UseOcr Extension Method
April 25, 2025 ยท View on GitHub
In the previous chapter, we explored the OcrPlugin class, which provides a convenient way to access OCR functionality from anywhere in your app. Now, let's learn about a more modern approach to integrating OCR into your MAUI applications: the UseOcr extension method.
Introduction to UseOcr Extension Method
Imagine you're building a house. You need to connect various systems like electricity, plumbing, and internet. Each connection requires specific knowledge and expertise. In a similar way, when building a MAUI app, you need to connect various services and features.
The UseOcr extension method is like calling a professional electrician who knows exactly how to wire your home's electrical system. With just one line of code, it properly connects the OCR functionality to your MAUI application, so everything works seamlessly together.
Why Do We Need UseOcr Extension Method?
Let's consider a practical example: you're building a receipt scanning app using .NET MAUI. You need to:
- Make OCR functionality available throughout your app
- Ensure the correct platform-specific implementation is used
- Follow modern dependency injection patterns
- Keep your code clean and maintainable
Without the UseOcr extension method, you'd need to:
- Manually register the OCR service with the dependency injection container
- Ensure the correct platform-specific implementation is selected
- Write boilerplate code in your app's startup
With the UseOcr extension method, you simply add one line of code to your app's startup, and everything is taken care of automatically.
Understanding UseOcr Through an Analogy
Think of the UseOcr extension method as plugging a new appliance into your home's electrical system:
- Your MAUI app is like your home
- The OCR functionality is like a new appliance (e.g., a refrigerator)
- The
UseOcrmethod is like the power outlet - Calling the method is like plugging in the appliance
Just as plugging in an appliance connects it to your home's electrical system, calling UseOcr connects the OCR functionality to your app's service system.
How UseOcr Works
The UseOcr extension method is remarkably simple:
public static MauiAppBuilder UseOcr(this MauiAppBuilder builder)
{
// Register the IOcrService implementation with the DI container
builder.Services.AddSingleton<IOcrService, OcrImplementation>();
return builder;
}
This code:
- Extends the
MauiAppBuilderclass with a new method calledUseOcr - Registers the
OcrImplementationclass as the implementation ofIOcrServicewith the dependency injection container - Returns the builder to allow for method chaining
Despite its simplicity, this method plays a crucial role in making OCR functionality available throughout your MAUI app.
Using UseOcr in Your MAUI App
Using the UseOcr extension method is incredibly simple. You just need to add one line of code to your app's startup:
// In your MauiProgram.cs
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
})
.UseOcr(); // Add this line to enable OCR
return builder.Build();
}
This code:
- Creates a new MAUI app builder
- Configures the app with standard settings
- Calls the
UseOcrextension method to register the OCR service - Builds and returns the MAUI app
With just that one line of code, OCR functionality is now available throughout your app through dependency injection.
Accessing OCR After Using UseOcr
Once you've called UseOcr in your app's startup, you can access the OCR service in your pages or view models through dependency injection:
public class ScanPage : ContentPage
{
private readonly IOcrService _ocrService;
// The IOcrService is automatically injected by the DI container
public ScanPage(IOcrService ocrService)
{
_ocrService = ocrService;
InitializeComponent();
}
private async void ScanButton_Clicked(object sender, EventArgs e)
{
// Take a photo
var photo = await TakePhotoAsync();
// Convert photo to byte array
byte[] imageBytes = ConvertToByteArray(photo);
// Recognize text using the injected OCR service
var result = await _ocrService.RecognizeTextAsync(imageBytes);
// Display the result
ResultLabel.Text = result.AllText;
}
}
This code:
- Declares a private field to hold the OCR service
- Accepts the OCR service through the constructor (constructor injection)
- Uses the OCR service to recognize text in a photo
The beauty of this approach is that you don't need to worry about creating or accessing the OCR service - it's automatically provided by the dependency injection container.
How UseOcr Works Behind the Scenes
When you call UseOcr and then access the OCR service, here's what happens:
sequenceDiagram
participant App as Your App
participant Builder as MauiAppBuilder
participant DI as DI Container
participant Factory as Service Factory
participant OCR as OcrImplementation
App->>Builder: UseOcr()
Builder->>DI: Register IOcrService โ OcrImplementation
Note over App,DI: Later, when a page is created...
App->>DI: Resolve IOcrService
DI->>Factory: Create OcrImplementation
Factory->>OCR: new OcrImplementation()
OCR-->>Factory: Return instance
Factory-->>DI: Return instance
DI-->>App: Return IOcrService
- During app startup, your app calls
UseOcron the MAUI app builder - The builder registers
OcrImplementationas the implementation ofIOcrServicewith the dependency injection container - Later, when a page or view model requests an
IOcrServicethrough its constructor - The DI container creates a new instance of
OcrImplementation(or returns an existing one for singletons) - The instance is passed to the page or view model
The Implementation of UseOcr
Let's look at the actual implementation of the UseOcr extension method in the library:
// From BuilderExtensions.cs
namespace Plugin.Maui.OCR;
public static class OcrServiceExtensions
{
public static MauiAppBuilder UseOcr(this MauiAppBuilder builder)
{
// Register the IOcrService implementation with the DI container.
// This ensures that whenever IOcrService is injected, the specific
// platform implementation is provided.
builder.Services.AddSingleton<IOcrService, OcrImplementation>();
return builder;
}
}
This code:
- Defines a static class called
OcrServiceExtensions - Defines an extension method called
UseOcrfor theMauiAppBuilderclass - Registers
OcrImplementationas a singleton implementation ofIOcrService - Returns the builder to allow for method chaining
The key part is AddSingleton<IOcrService, OcrImplementation>(), which tells the DI container to create a single instance of OcrImplementation and return it whenever an IOcrService is requested.
UseOcr vs. OcrPlugin: Which to Use?
Now that we've learned about both UseOcr and OcrPlugin, you might be wondering which one to use in your app. Here's a comparison:
UseOcr (Dependency Injection Approach)
- Pros:
- Modern approach that follows MAUI best practices
- Works well with other services that use dependency injection
- Makes testing easier by allowing you to inject mock services
- Cleaner architecture with explicit dependencies
- Cons:
- Requires passing the service to each class that needs it
- Slightly more setup code
OcrPlugin (Static Access Approach)
- Pros:
- Simpler to use with direct access from anywhere
- No need to pass the service between classes
- Works well in smaller apps with simpler architecture
- Cons:
- Less testable because it's harder to replace with mock services
- Not as clean architecturally
- Doesn't follow modern dependency injection patterns
In general, we recommend using UseOcr for new MAUI apps, as it follows modern best practices and provides more flexibility. However, OcrPlugin is still a valid option, especially for smaller apps or if you prefer the simplicity of static access.
Real-World Example: Receipt Scanner
Let's put everything together in a real-world example of a receipt scanner using the UseOcr approach:
// In MauiProgram.cs
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseOcr(); // Register OCR service
// Register pages and view models
builder.Services.AddTransient<ScanPage>();
builder.Services.AddTransient<ScanViewModel>();
return builder.Build();
}
// In ScanViewModel.cs
public class ScanViewModel
{
private readonly IOcrService _ocrService;
public ScanViewModel(IOcrService ocrService)
{
_ocrService = ocrService;
}
public async Task<string> ScanReceiptAsync(byte[] imageBytes)
{
// Create options for receipt scanning
var options = new OcrOptions(
language: "en",
patternConfig: new OcrPatternConfig(
@"\$\d+\.\d{2}" // Pattern for prices
)
);
// Recognize text in the receipt
var result = await _ocrService.RecognizeTextAsync(imageBytes, options);
// Return the total amount if found
if (result.MatchedValues.Count > 0)
{
return $"Total: {result.MatchedValues[0]}";
}
return "No total found";
}
}
This code:
- Registers the OCR service using
UseOcrin the app's startup - Creates a view model that accepts the OCR service through its constructor
- Uses the OCR service to scan receipts and extract the total amount
Advanced Usage: Registering a Custom Implementation
In some cases, you might want to use a custom implementation of IOcrService instead of the default one. For example, you might want to add logging, caching, or other features to the OCR service.
You can do this by registering your custom implementation before calling UseOcr:
// In MauiProgram.cs
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
// Register your custom OCR service
builder.Services.AddSingleton<IOcrService, MyCustomOcrService>();
// Call UseOcr (it won't override your custom registration)
builder.UseOcr();
return builder.Build();
}
This code:
- Registers your custom OCR service with the DI container
- Calls
UseOcr, which would normally register the default implementation - Because your custom registration comes first, it takes precedence
The UseOcr method is designed to be safe to call even if you've already registered a custom implementation. It won't override your custom registration.
Conclusion
In this chapter, we've explored the UseOcr extension method, which provides a modern, clean way to integrate OCR functionality into your MAUI applications. We've seen how it registers the OCR service with the dependency injection container, making it available throughout your app.
The UseOcr extension method is a small but powerful tool that follows MAUI best practices and makes it easy to add OCR capabilities to your app. By providing a simple, one-line integration point, it allows you to focus on your app's features rather than worrying about how to wire up the OCR service.
In the next chapter, we'll explore a MainPage (Sample App) that demonstrates how to use OCR in a real-world scenario.
Key Takeaways
UseOcris an extension method that registers the OCR service with the dependency injection container- It provides a modern, clean way to integrate OCR functionality into your MAUI applications
- You can access the OCR service through constructor injection in your pages and view models
- It follows MAUI best practices and makes testing easier
- You can register a custom implementation of
IOcrServiceif needed - It's designed to be safe to call even if you've already registered a custom implementation
Generated by AI Codebase Knowledge Builder