-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[core] use factory methods for registering services #16741
[core] use factory methods for registering services #16741
Conversation
7406958
to
d34025a
Compare
d34025a
to
493bcc8
Compare
493bcc8
to
196b7ce
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. At least with your updated change there should be no behavior regression at all, even if perhaps it turns out the CellRenderer is not needed a tall.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides the removal of the Cell registration, this is good to go! And maybe a rebase/merge from main to fix the CI builds.
In .NET 8 Preview 7, we noticed a regression in startup around: .NET 8 Preview 6: 45.35ms microsoft.maui!Microsoft.Maui.Hosting.MauiAppBuilder.Build() .NET 8 Preview 7: 62.17ms microsoft.maui!Microsoft.Maui.Hosting.MauiAppBuilder.Build() This may have been related to: dotnet/runtime#87183 Which should be improved by: dotnet/runtime#89964 In reviewing the traces, we noticed several places where MAUI was registering services like: services.AddTransient<IFoo, Foo>(); Where we could instead do: services.AddTransient<IFoo>(_ => new Foo()); Where this registration avoids any System.Reflection work at startup. Microsoft.Extensions.DI can just call the factory method instead. I expanded upon `BannedSymbols.txt` like we did in e7812b0, to ban cases of `AddTransient` and `AddScoped` that might be used accidentally. This resulted in banning the slow versions of these APIs like: Microsoft.Maui.Hosting.ImageSourceServiceCollectionExtensions.AddService Microsoft.Maui.Hosting.MauiHandlersCollectionExtensions.AddHandler Microsoft.Maui.Hosting.MauiHandlersCollectionExtensions.TryAddHandler I also introduced public, fast versions of methods in `MauiHandlersCollectionExtensions`. With this change in place, I could see the difference in: Before: 11.24ms microsoft.extensions.dependencyinjection!Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine..ctor After: 6.29ms microsoft.extensions.dependencyinjection!Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine..ctor Which resulted in an overall faster startup of a `dotnet new maui` app on a Pixel 5: Average(ms): 691 Std Err(ms): 3.00370142028502 Std Dev(ms): 9.49853789918334 Average(ms): 687.8 Std Err(ms): 4.04365071576553 Std Dev(ms): 12.7871463239892 This is an average of 10 runs. Note that this was built with main, and so we have an out-of-date AOT profile compared to the `net8.0` branch.
c5a75c4
to
e9d2075
Compare
@@ -7,6 +7,7 @@ | |||
<RootNamespace>Microsoft.Maui.DeviceTests</RootNamespace> | |||
<AssemblyName>Microsoft.Maui.Controls.DeviceTests</AssemblyName> | |||
<NoWarn>$(NoWarn),CA1416</NoWarn> | |||
<IsTestProject>true</IsTestProject> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This disables the BannedApis analyzer for certain projects, added in: e7812b0
It's fine to use these in tests.
public static IImageSourceServiceCollection AddService<TImageSource, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImageSourceService>(this IImageSourceServiceCollection services) | ||
where TImageSource : IImageSource | ||
where TImageSourceService : class, IImageSourceService<TImageSource> | ||
{ | ||
#pragma warning disable RS0030 // Do not use banned APIs, the current method is also banned |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add a overload that doesn't use this ? And use it ourselfs ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use the wrong one, it's a "banned API" and we'd get a build error. This one doesn't seem to be highly used, but I'm open.
@jonathanpeppers @mattleibow so one thing I realized about this PR is that this will disable our ability to do dependency injection with handlers. I was more hoping we were going to move to instantiating all the handlers via I realize users could re-register the handler but that's a bit awkward. Will we eventually be able to move these back once the issue that regressed with runtime is fixed? |
@PureWeen no, it shouldn't. There is an example how to do this in e7812b0:
If you want to do constructor injection, you just have to pass the parameters in. Keep in mind customers won't have to do any of this in their apps. They can register things however they like. |
We should avoid DI features that use System.Reflection -- if we want a fast startup time. They might have a source generator one day, but that is some future .NET 9 thing. |
yea, I was thinking from our performance analysis work in NET6 we'd mostly determined it didn't really matter. I was just hopeful we'd be able to avoid needing to be prescriptive about how to register. If this is something users need to be aware of in general, we might also look at updating our docs https://learn.microsoft.com/en-us/dotnet/architecture/maui/dependency-injection#registration Or eventually adding to the queue of things that would be neat for a MAUI analyzer :-) |
This reverts commit b0bba51. # Conflicts: # src/Controls/src/Xaml/Hosting/AppHostBuilderExtensions.cs # src/Core/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt
* Revert "[core] factory methods for registering services, part 2 (#17004)" This reverts commit 79a44ff. * Revert "[android] fix DI registration for Frame, ListView, TableView (#16989)" This reverts commit 136f21d. * Revert "[core] use factory methods for registering services (#16741)" This reverts commit b0bba51. # Conflicts: # src/Controls/src/Xaml/Hosting/AppHostBuilderExtensions.cs # src/Core/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt * Revert "Revert "[core] factory methods for registering services, part 2 (#17004)"" This reverts commit ed9a1fc. # Conflicts: # eng/BannedSymbols.txt # src/BlazorWebView/src/SharedSource/BlazorWebViewServiceCollectionExtensions.cs * Restore some changes (so hopefully it builds now?) Diff is also smaller --------- Co-authored-by: Jonathan Peppers <[email protected]>
In .NET 8 Preview 7, we noticed a regression in startup around:
This may have been related to:
dotnet/runtime#87183
Which should be improved by:
dotnet/runtime#89964
In reviewing the traces, we noticed several places where MAUI was registering services like:
Where we could instead do:
Where this registration avoids any System.Reflection work at startup. Microsoft.Extensions.DI can just call the factory method instead.
I expanded upon
BannedSymbols.txt
like we did in e7812b0, to ban cases ofAddTransient
andAddScoped
that might be used accidentally.This resulted in banning the slow versions of these APIs like:
I also introduced public, fast versions of methods in
MauiHandlersCollectionExtensions
.With this change in place, I could see the difference in:
Which resulted in an overall faster startup of a
dotnet new maui
app on a Pixel 5:This is an average of 10 runs. Note that this was built with main, and so we have an out-of-date AOT profile compared to the
net8.0
branch.