Skip to content

Commit

Permalink
Find MauiProgram namespace the app is running in
Browse files Browse the repository at this point in the history
  • Loading branch information
BurkusCat committed Nov 11, 2023
1 parent f5b35b0 commit a0efbbf
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 30 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<Using Remove="Burkus.Mvvm.Maui" />
Expand Down
8 changes: 8 additions & 0 deletions samples/DemoApp/DemoApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

<!-- Source generators -->
<!-- Uncomment to debug the output of the source generators
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
-->

<ItemGroup>
<None Remove="Resources\Images\contacts.png" />
<None Remove="Resources\Images\reminders.png" />
Expand Down
73 changes: 44 additions & 29 deletions src/Burkus.Mvvm.Maui.SourceGenerators/AppSourceGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
using System;
using System.Linq;
using System.Text;

Expand All @@ -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")))

Check warning on line 30 in src/Burkus.Mvvm.Maui.SourceGenerators/AppSourceGenerator.cs

View workflow job for this annotation

GitHub Actions / build-plugin-ci

Use 'SymbolEqualityComparer' when comparing symbols
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 = """
// <auto-generated>
// 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.
// </auto-generated>

partial class App : Application
{
protected override Window CreateWindow(IActivationState? activationState)
{
Current.MainPage = new NavigationPage();

var burkusMvvmBuilder = ServiceResolver.Resolve<IBurkusMvvmBuilder>();
var navigationService = ServiceResolver.Resolve<INavigationService>();
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 = $@"// <auto-generated>
// 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.
// </auto-generated>
namespace {mauiProgram.ContainingNamespace.ToDisplayString()};
public partial class App : Application
{{
protected override Window CreateWindow(IActivationState? activationState)
{{
Current.MainPage = new NavigationPage();
var burkusMvvmBuilder = ServiceResolver.Resolve<IBurkusMvvmBuilder>();
var navigationService = ServiceResolver.Resolve<INavigationService>();
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));
Expand Down

0 comments on commit a0efbbf

Please sign in to comment.