balintn
balintn

Reputation: 1453

How to implement interceptors/aspects in a dotnet Maui app?

I'm implementing a dotnet Maui app, and got to the point when I'd need some aspects to hanlde errors and certain responses. In the past, I implemented interceptors using Castle Windsor, but how can I do it in Maui?

The dev environment is Visual Studio 2022 v17.6.2 Maui versions:

Installed Workload Id      Manifest Version       Installation Source
---------------------------------------------------------------------
maui-ios                   7.0.86/7.0.100         VS 17.6.33723.286
android                    33.0.46/7.0.100        VS 17.6.33723.286
maui-windows               7.0.86/7.0.100         VS 17.6.33723.286
maui-maccatalyst           7.0.86/7.0.100         VS 17.6.33723.286
maccatalyst                16.4.7054/7.0.100      VS 17.6.33723.286
ios                        16.4.7054/7.0.100      VS 17.6.33723.286
maui-android               7.0.86/7.0.100         VS 17.6.33723.286

Targetframework: net7

Problem is that the built in DI resolver doesn't support interceptors (unless I missed something).

Upvotes: 1

Views: 584

Answers (1)

balintn
balintn

Reputation: 1453

Here's how I did it.

Choosing the DI provider

Dotnet built in one has no support for interceptors. Tried Castle Windsor, but the nuget package added a scary list of dependencies, so looked for something else. Then Autofac, and the dependency list was much friendlier (haven't actually checked the additional binary size in the deployed app though). Decided to use Autofac.

Steps

  • Added Autofac nuget package
  • Added Autofac container registration to MauiProgram.cs (based on https://stackoverflow.com/questions/73604106/how-to-use-autofac-with-net-maui)
public static MauiApp CreateMauiApp()
{
  var builder = MauiApp.CreateBuilder();
  builder
    .UseMauiApp<App>()
    .ConfigureFonts(fonts =>  { ... })
    .ConfigureContainer(new AutofacServiceProviderFactory(), autofacBuilder => {
        // Registrations
        // Don't call the autofacBuilder.Build() here - it is called behind
        // the scenes
        autofacBuilder.RegisterType<Logic>().As<ILogic>() // where Logic is the type to add the aspect to
            .EnableClassInterceptors()
            .InterceptedBy(typeof(LoggingAspect));  // LoggingAspect is the interceptor to implement logging
        autofacBuilder.RegisterType<MainPage>();  // See step below, had to add DI registration for the Maui MainPage
        autofacBuilder.RegisterType<LoggingAspect>();
});
  • Added Autofac.Extensions.DependencyInjection nuget package
  • Created ILogic interface and Logic class (as demonstration, thi is the class to intercept)
  • Registered ILogic, Logic as a DI component in MauiProgram.cs with Autofac (see code sample above)
  • Registered MainPage with Autofac (see code sample above)

Added an aspect (see https://levelup.gitconnected.com/embracing-aspect-oriented-programming-in-net-2640f9ace519)

  • Install nuget package Autofac.Extras.DynamicProxy
  • Create logging aspect (LoggingAspect.cs)
  • Register interceptor for the class in DI registration (see code sample above)

At this point I was faced with intercepting both sync and async methods, and remembered it was not easy. Luckily I had my own library from before, added the nuget package BaseInterceptors and implemented the logging aspect based on Example 2 at https://www.nuget.org/packages/BaseInterceptors

Upvotes: 1

Related Questions