From a0efbbf8020c25179b438a75cee37cc2e85d1b23 Mon Sep 17 00:00:00 2001 From: Ronan Burke Date: Sat, 11 Nov 2023 19:11:37 +0000 Subject: [PATCH] Find MauiProgram namespace the app is running in --- README.md | 3 +- samples/DemoApp/DemoApp.csproj | 8 ++ .../AppSourceGenerator.cs | 73 +++++++++++-------- 3 files changed, 54 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index d677ec8..0a6a772 100644 --- a/README.md +++ b/README.md @@ -402,7 +402,8 @@ See the [IDialogService interface in the repository](https://github.com/BurkusCa ## Advanced / complexities The below are some things of note that may help prevent issues from arising: -- When you inherit from `BurkusMvvmApplication`, the `MainPage` of the app will be automatically set to a `NavigationPage`. This means the first page you push can be a `ContentPage` rather than needing to push a `NavigationPage`. This may change in the future. +- The `MainPage` of the app will be automatically set to a `NavigationPage`. This means the first page you push can be a `ContentPage` rather than needing to push a `NavigationPage`. This may change in the future. +- A source generator will automatically add code overriding `Window CreateWindow(IActivationState? activationState)` in your `App.xaml.cs` class. - Adding this package to a project will automatically import the `Burkus.Mvvm.Maui` namespace globally if you have [`ImplicitUsings`](https://devblogs.microsoft.com/dotnet/welcome-to-csharp-10/#implicit-usings) enabled in your project. You can opt out of this by including the following in your `.csproj` file: ``` xml diff --git a/samples/DemoApp/DemoApp.csproj b/samples/DemoApp/DemoApp.csproj index 76259df..d509f54 100644 --- a/samples/DemoApp/DemoApp.csproj +++ b/samples/DemoApp/DemoApp.csproj @@ -47,6 +47,14 @@ + + + diff --git a/src/Burkus.Mvvm.Maui.SourceGenerators/AppSourceGenerator.cs b/src/Burkus.Mvvm.Maui.SourceGenerators/AppSourceGenerator.cs index 1b713be..39309c5 100644 --- a/src/Burkus.Mvvm.Maui.SourceGenerators/AppSourceGenerator.cs +++ b/src/Burkus.Mvvm.Maui.SourceGenerators/AppSourceGenerator.cs @@ -1,6 +1,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; +using System; using System.Linq; using System.Text; @@ -27,37 +28,51 @@ public void Execute(GeneratorExecutionContext context) // check if the App class is partial and inherits from Application var appSymbol = semanticModel.GetDeclaredSymbol(receiver.AppClass); if (appSymbol is null || !isPartial || !appSymbol.BaseType.Equals(semanticModel.Compilation.GetTypeByMetadataName("Microsoft.Maui.Controls.Application"))) - return; + { + throw new Exception("You must have a partial class called \"App\" that inherits from Application in your .NET MAUI project."); + } + + // get the MAUI program we are running in + + var assembly = context.Compilation.Assembly; + var mauiProgramName = $"{assembly.Name}.MauiProgram"; + var mauiProgram = context.Compilation + .GetTypeByMetadataName(mauiProgramName); + + if (mauiProgram is null) + { + throw new Exception("You must have a class called \"MauiProgram\" in your .NET MAUI project."); + } // generate the source code for the CreateWindow method - var sourceBuilder = """ - // - // This code was generated by a tool. Burkus.Mvvm.Maui generated this. - // - // Changes to this file may cause incorrect behavior and will be lost if - // the code is regenerated. - // - - partial class App : Application - { - protected override Window CreateWindow(IActivationState? activationState) - { - Current.MainPage = new NavigationPage(); - - var burkusMvvmBuilder = ServiceResolver.Resolve(); - var navigationService = ServiceResolver.Resolve(); - var serviceProvider = ServiceResolver.GetServiceProvider(); - - // perform the user's desired initialization logic - if (burkusMvvmBuilder.onStartFunc != null) - { - burkusMvvmBuilder.onStartFunc.Invoke(navigationService, serviceProvider); - } - - return base.CreateWindow(activationState); - } - } - """; + var sourceBuilder = $@"// +// This code was generated by a tool. Burkus.Mvvm.Maui generated this. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// + +namespace {mauiProgram.ContainingNamespace.ToDisplayString()}; + +public partial class App : Application +{{ + protected override Window CreateWindow(IActivationState? activationState) + {{ + Current.MainPage = new NavigationPage(); + + var burkusMvvmBuilder = ServiceResolver.Resolve(); + var navigationService = ServiceResolver.Resolve(); + var serviceProvider = ServiceResolver.GetServiceProvider(); + + // perform the user's desired initialization logic + if (burkusMvvmBuilder.onStartFunc != null) + {{ + burkusMvvmBuilder.onStartFunc.Invoke(navigationService, serviceProvider); + }} + + return base.CreateWindow(activationState); + }} +}}"; // add the generated source file to the compilation context.AddSource("App-BurkusMvvmApplication.g", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));