Search code examples
c#.netdependency-injectionmauimaui-blazor

Net MAUI Dependency injection does not work


I have tried to configure dependency injection in Net Maui app. I followed few online tutorials, read through several stackoverflow threads, however nothing seems to work. After considerable amount of tinkering with this stuff, I am clueless why this is not working.

MauiApp is rather straight forward. I set here: Serilog, config, and classes from project library. This should work.

        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            
            InitializeLogger();

            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                });

            // Configuration
            using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("BookLibrary.appsettings.json");
            var config = new ConfigurationBuilder().AddJsonStream(stream).Build();
            builder.Configuration.AddConfiguration(config);

            // Logging
            builder.Logging.AddSerilog(dispose: true);

            builder.Services.AddTransient<IBooksDao, BooksDao>();
            builder.Services.AddTransient<IChaptersDao, ChaptersDao>();
            builder.Services.AddTransient<IPagesDao, PagesDao>();
            builder.Services.AddTransient<IBookWriter, BookWriter>();

            builder.Services.AddSingleton<MainPage>();
            builder.Services.AddMauiBlazorWebView();

#if DEBUG
            builder.Services.AddBlazorWebViewDeveloperTools();
            builder.Logging.AddDebug();
#endif

            return builder.Build();
        }
        private static void InitializeLogger()
        {
            var flushInterval = new TimeSpan(0, 0, 1);
            var file = Path.Combine(AppContext.BaseDirectory, "Logs/Log_.txt");
            
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Verbose()
                .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
                .Enrich.FromLogContext()
                .WriteTo.File(file, 
                    flushToDiskInterval: flushInterval, 
                    encoding: System.Text.Encoding.UTF8, 
                    rollingInterval: RollingInterval.Day, 
                    retainedFileCountLimit: 22)
                .CreateLogger();
        }
    }

MainPage class, in the constructor I inject all things that I need.

    public partial class MainPage : ContentPage
    {
        private readonly IConfiguration _configuration;
        private readonly ILogger _log;
        private readonly IBookWriter _writer;

        public MainPage(IConfiguration configuration, ILogger log, IBookWriter writer)
        {
            _configuration = configuration;
            _log = log;
            _writer = writer;
            
            InitializeComponent();
        }
    }

However in the App class there is an error connected to the MainPage() (it has red underscore) and info that there is no argument for required parameter configuration. If I remove the configuration parameter, then the problem switches to log and so one. It looks like the DI is not working at all. I have even installed nugets for: Microsoft.Extensions.Configuation.Binder, Microsoft.Extensions.Configuation.Json and Serilog.Extensions.Logging, but nothing seems to help.

    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            MainPage = new MainPage();
        }

    }

I have obviously done a mistake somewhere, but I am unable to find it on my own.


Solution

  • You have registered the DI for the MainPage, so you don't have to use new MainPage(). It should be:

    public partial class App : Application
        {
            public App(MainPage mainpage)
            {
                InitializeComponent();
    
                MainPage = mainpage;
            }
    
        }