Add AOT Compatibility (#1820)
* Mark relevant assemblies as AOT compatible * Fix straightforward trimming warnings * Simplify ValueConverterExtension.IsValidTargetType * Update ValueConverterExtension.shared.cs * Add `<IsAotCompatible>true</IsAotCompatible>` to `CommunityToolkit.Maui.Camera` * Add AOT WarningsAsErrors * Promote Trimmer + AOT Warnings to Errors * Fix missing comma * Publish Sample app using AOT * Resolve Trim Warnings * `dotnet format` * Remove AOT from Tizen sample * Replace `Enum.GetValues(Type)` with `EnumGetValues<T>()` * Remove 'android-arm' and 'android-x86' * Fix AOT on Windows * Remove Android AOT * Set `win-x64` runtime for default Release builds * Fix naming * Update CommunityToolkit.Maui.Sample.csproj --------- Co-authored-by: Brandon Minnick <13558917+brminnick@users.noreply.github.com>
This commit is contained in:
Родитель
c28eefa0cc
Коммит
725dd4153b
|
@ -12,7 +12,10 @@
|
|||
<GenerateErrorForMissingTargetingPacks>false</GenerateErrorForMissingTargetingPacks>
|
||||
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
||||
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||
<IsTrimmable>false</IsTrimmable>
|
||||
|
||||
<!-- https://learn.microsoft.com/dotnet/core/deploying/native-aot/?tabs=net8plus%2Cwindows -->
|
||||
<StripSymbols>false</StripSymbols>
|
||||
<TrimmerSingleWarn>false</TrimmerSingleWarn>
|
||||
|
||||
<!-- WarningsAsErrors
|
||||
CS0419: Ambiguous reference in cref attribute
|
||||
|
@ -37,8 +40,27 @@
|
|||
CS1723: XML comment has cref attribute that refers to a type parameter
|
||||
CS1734: XML comment has a paramref tag, but there is no parameter by that name
|
||||
xUnit1012: Null should not be used for type parameter
|
||||
xUnit2021: Assert.ThrowsAsync is async. The resulting task should be awaited -->
|
||||
<WarningsAsErrors>nullable,CS0419,CS1570,CS1571,CS1572,CS1573,CS1574,CS1580,CS1581,CS1584,CS1587,CS1589,CS1590,CS1591,CS1592,CS1598,CS1658,CS1710,CS1711,CS1712,CS1723,CS1734,xUnit1012,xUnit2021</WarningsAsErrors>
|
||||
xUnit2021: Assert.ThrowsAsync is async. The resulting task should be awaited
|
||||
IL2***: Trim Warnings
|
||||
IL3***: AOT Warnings -->
|
||||
<WarningsAsErrors>nullable,
|
||||
CS0419,CS1570,CS1571,CS1572,CS1573,CS1574,CS1580,CS1581,CS1584,CS1587,CS1589,CS1590,CS1591,CS1592,CS1598,CS1658,CS1710,CS1711,CS1712,CS1723,CS1734,
|
||||
xUnit1012,xUnit2021,
|
||||
IL2001,IL2002,IL2003,IL2004,IL2005,IL2006,IL2007,IL2008,IL2009,
|
||||
IL2010,IL2011,IL2012,IL2013,IL2014,IL2015,IL2016,IL2017,IL2018,IL2019,
|
||||
IL2020,IL2021,IL2022,IL2023,IL2024,IL2025,IL2026,IL2027,IL2028,IL2029,
|
||||
IL2030,IL2031,IL2032,IL2033,IL2034,IL2035,IL2036,IL2037,IL2038,IL2039,
|
||||
IL2040,IL2041,IL2042,IL2043,IL2044,IL2045,IL2046,IL2047,IL2048,IL2049,
|
||||
IL2050,IL2051,IL2052,IL2053,IL2054,IL2055,IL2056,IL2057,IL2058,IL2059,
|
||||
IL2060,IL2061,IL2062,IL2063,IL2064,IL2065,IL2066,IL2067,IL2068,IL2069,
|
||||
IL2070,IL2071,IL2072,IL2073,IL2074,IL2075,IL2076,IL2077,IL2078,IL2079,
|
||||
IL2080,IL2081,IL2082,IL2083,IL2084,IL2085,IL2086,IL2087,IL2088,IL2089,
|
||||
IL2090,IL2091,IL2092,IL2093,IL2094,IL2095,IL2096,IL2097,IL2098,IL2099,
|
||||
IL2100,IL2101,IL2102,IL2103,IL2104,IL2105,IL2106,IL2107,IL2108,IL2109,
|
||||
IL2110,IL2111,IL2112,IL2113,IL2114,IL2115,IL2116,IL2117,IL2118,IL2119,
|
||||
IL2120,IL2121,IL2122,
|
||||
IL3050,IL3051,IL3052,IL3053,IL3054,IL3055,IL3056
|
||||
</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -33,6 +33,16 @@
|
|||
<!--<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>-->
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'
|
||||
AND $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) != 'tizen'
|
||||
AND $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) != 'android'
|
||||
AND $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) != 'windows'">
|
||||
<!-- Ahead-of-time compilation is not yet supported net8.0-tizen -->
|
||||
<!-- Cross-OS native compilation is not supported net8.0-android -->
|
||||
<!-- Only iOS + MacCatalyst support AOT in .NET 8 -->
|
||||
<PublishAot>true</PublishAot>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- App Icon -->
|
||||
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
|
||||
|
@ -77,6 +87,10 @@
|
|||
<ProjectReference Include="..\..\src\CommunityToolkit.Maui.Maps\CommunityToolkit.Maui.Maps.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))=='windows' and $(Configuration) == 'Release'">
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))=='android'">
|
||||
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
||||
<RuntimeIdentifiers>android-arm;android-arm64;android-x86;android-x64</RuntimeIdentifiers>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using CommunityToolkit.Maui.ApplicationModel;
|
||||
using CommunityToolkit.Maui.Maps;
|
||||
using CommunityToolkit.Maui.Markup;
|
||||
|
@ -266,7 +267,7 @@ public static class MauiProgram
|
|||
services.AddSingleton<ITextToSpeech>(TextToSpeech.Default);
|
||||
}
|
||||
|
||||
static IServiceCollection AddTransientWithShellRoute<TPage, TViewModel>(this IServiceCollection services) where TPage : BasePage<TViewModel>
|
||||
static IServiceCollection AddTransientWithShellRoute<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TPage, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TViewModel>(this IServiceCollection services) where TPage : BasePage<TViewModel>
|
||||
where TViewModel : BaseViewModel
|
||||
{
|
||||
return services.AddTransientWithShellRoute<TPage, TViewModel>(AppShell.GetPageRoute<TViewModel>());
|
||||
|
|
|
@ -4,5 +4,5 @@ namespace CommunityToolkit.Maui.Sample.ViewModels.Behaviors;
|
|||
|
||||
public class CharactersValidationBehaviorViewModel : BaseViewModel
|
||||
{
|
||||
public IReadOnlyList<CharacterType> CharacterTypes { get; } = Enum.GetValues(typeof(CharacterType)).Cast<CharacterType>().ToList();
|
||||
public IReadOnlyList<CharacterType> CharacterTypes { get; } = [.. Enum.GetValues<CharacterType>()];
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);$(NetVersion)-tizen</TargetFrameworks>
|
||||
<SingleProject>true</SingleProject>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IsAotCompatible>true</IsAotCompatible>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">13.1</SupportedOSPlatformVersion>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);$(NetVersion)-tizen</TargetFrameworks>
|
||||
<SingleProject>true</SingleProject>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IsAotCompatible>true</IsAotCompatible>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">13.1</SupportedOSPlatformVersion>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);$(NetVersion)-tizen</TargetFrameworks>
|
||||
<SingleProject>true</SingleProject>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IsAotCompatible>true</IsAotCompatible>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">13.1</SupportedOSPlatformVersion>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Globalization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Maui.Controls.Maps;
|
||||
using Microsoft.Maui.Handlers;
|
||||
|
@ -40,8 +41,15 @@ public partial class MapHandlerWindows : MapHandler
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
[RequiresDynamicCode("Calls System.Text.Json.JsonSerializer.Deserialize<TValue>(String, JsonSerializerOptions)")]
|
||||
[RequiresUnreferencedCode("Calls System.Text.Json.JsonSerializer.Deserialize<TValue>(String, JsonSerializerOptions)")]
|
||||
#if NET8_0 // Should be fixed in .NET 9
|
||||
#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
|
||||
#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
|
||||
protected override FrameworkElement CreatePlatformView()
|
||||
#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
|
||||
#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
|
||||
#endif
|
||||
{
|
||||
if (string.IsNullOrEmpty(MapsKey))
|
||||
{
|
||||
|
@ -57,7 +65,15 @@ public partial class MapHandlerWindows : MapHandler
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[RequiresDynamicCode("Calls System.Text.Json.JsonSerializer.Deserialize<TValue>(String, JsonSerializerOptions)")]
|
||||
[RequiresUnreferencedCode("Calls System.Text.Json.JsonSerializer.Deserialize<TValue>(String, JsonSerializerOptions)")]
|
||||
#if NET8_0 // Should be fixed in .NET 9
|
||||
#pragma warning disable IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
|
||||
#pragma warning disable IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
|
||||
protected override void DisconnectHandler(FrameworkElement platformView)
|
||||
#pragma warning restore IL3051 // 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
|
||||
#pragma warning restore IL2046 // 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
|
||||
#endif
|
||||
{
|
||||
if (PlatformView is MauiWebView mauiWebView)
|
||||
{
|
||||
|
@ -396,6 +412,8 @@ public partial class MapHandlerWindows : MapHandler
|
|||
}
|
||||
}
|
||||
|
||||
[RequiresDynamicCode("Calls System.Text.Json.JsonSerializer.Deserialize<TValue>(String, JsonSerializerOptions)")]
|
||||
[RequiresUnreferencedCode("Calls System.Text.Json.JsonSerializer.Deserialize<TValue>(String, JsonSerializerOptions)")]
|
||||
void WebViewWebMessageReceived(WebView2 sender, CoreWebView2WebMessageReceivedEventArgs args)
|
||||
{
|
||||
// For some reason the web message is empty
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);$(NetVersion)-tizen</TargetFrameworks>
|
||||
<SingleProject>true</SingleProject>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IsAotCompatible>true</IsAotCompatible>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">13.1</SupportedOSPlatformVersion>
|
||||
|
|
|
@ -11,8 +11,8 @@ public partial class MediaElementHandler : ViewHandler<MediaElement, MauiMediaEl
|
|||
/// <see cref="MediaElement"/> and platform counterpart.
|
||||
/// </summary>
|
||||
/// <param name="handler">The associated handler.</param>
|
||||
/// <param name="MediaElement">The associated <see cref="MediaElement"/> instance.</param>
|
||||
public static void ShouldLoopPlayback(MediaElementHandler handler, MediaElement MediaElement)
|
||||
/// <param name="mediaElement">The associated <see cref="MediaElement"/> instance.</param>
|
||||
public static void ShouldLoopPlayback(MediaElementHandler handler, MediaElement mediaElement)
|
||||
{
|
||||
handler.mediaManager?.UpdateShouldLoopPlayback();
|
||||
}
|
||||
|
|
|
@ -394,7 +394,7 @@ public partial class MediaManager : IDisposable
|
|||
return res;
|
||||
}
|
||||
|
||||
foreach (AppFW.ResourceManager.Category category in Enum.GetValues(typeof(AppFW.ResourceManager.Category)))
|
||||
foreach (AppFW.ResourceManager.Category category in Enum.GetValues<AppFW.ResourceManager.Category>())
|
||||
{
|
||||
var path = AppFW.ResourceManager.TryGetPath(category, res);
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CommunityToolkit.Maui.Behaviors;
|
||||
|
@ -59,6 +60,7 @@ public abstract class BaseBehavior<TView> : Behavior<TView>, ICommunityToolkitBe
|
|||
/// <returns></returns>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete($"{nameof(IsBound)} is no longer used by {nameof(CommunityToolkit)}.{nameof(CommunityToolkit.Maui)} and will be removed in a future release")]
|
||||
[RequiresUnreferencedCode($"The {nameof(IsBound)} method is not trim compatible")]
|
||||
protected bool IsBound(BindableProperty property, BindingBase? defaultBinding = null)
|
||||
{
|
||||
var getContextMethod = typeof(BindableObject).GetRuntimeMethods().FirstOrDefault(m => m.Name is "GetContext");
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<TargetFrameworks Condition="'$(IncludeTizenTargetFrameworks)' == 'true'">$(TargetFrameworks);$(NetVersion)-tizen</TargetFrameworks>
|
||||
<SingleProject>true</SingleProject>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IsAotCompatible>true</IsAotCompatible>
|
||||
|
||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GeneratedFiles</CompilerGeneratedFilesOutputPath>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using CommunityToolkit.Maui.Extensions;
|
||||
|
||||
|
@ -10,7 +11,7 @@ namespace CommunityToolkit.Maui.Converters;
|
|||
/// <typeparam name="TFrom">Type of the input value.</typeparam>
|
||||
/// <typeparam name="TTo">Type of the output value.</typeparam>
|
||||
/// <typeparam name="TParam">Type of parameter</typeparam>
|
||||
public abstract class BaseConverter<TFrom, TTo, TParam> : ValueConverterExtension, ICommunityToolkitValueConverter
|
||||
public abstract class BaseConverter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TFrom, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TTo, TParam> : ValueConverterExtension, ICommunityToolkitValueConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Default value to return when <see cref="IValueConverter.Convert(object?, Type, object?, CultureInfo?)"/> throws an <see cref="Exception"/>.
|
||||
|
@ -25,9 +26,11 @@ public abstract class BaseConverter<TFrom, TTo, TParam> : ValueConverterExtensio
|
|||
public abstract TFrom DefaultConvertBackReturnValue { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
||||
public Type FromType { get; } = typeof(TFrom);
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
||||
public Type ToType { get; } = typeof(TTo);
|
||||
|
||||
/// <summary>
|
||||
|
@ -57,7 +60,7 @@ public abstract class BaseConverter<TFrom, TTo, TParam> : ValueConverterExtensio
|
|||
public abstract TFrom ConvertBackTo(TTo value, TParam parameter, CultureInfo? culture);
|
||||
|
||||
/// <inheritdoc/>
|
||||
object? ICommunityToolkitValueConverter.ConvertBack(object? value, Type targetType, object? parameter, CultureInfo? culture)
|
||||
object? ICommunityToolkitValueConverter.ConvertBack(object? value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type targetType, object? parameter, CultureInfo? culture)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -76,7 +79,7 @@ public abstract class BaseConverter<TFrom, TTo, TParam> : ValueConverterExtensio
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
object? ICommunityToolkitValueConverter.Convert(object? value, Type targetType, object? parameter, CultureInfo? culture)
|
||||
object? ICommunityToolkitValueConverter.Convert(object? value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type targetType, object? parameter, CultureInfo? culture)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -100,7 +103,7 @@ public abstract class BaseConverter<TFrom, TTo, TParam> : ValueConverterExtensio
|
|||
/// </summary>
|
||||
/// <typeparam name="TFrom">Type of the input value.</typeparam>
|
||||
/// <typeparam name="TTo">Type of the output value.</typeparam>
|
||||
public abstract class BaseConverter<TFrom, TTo> : ValueConverterExtension, ICommunityToolkitValueConverter
|
||||
public abstract class BaseConverter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TFrom, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TTo> : ValueConverterExtension, ICommunityToolkitValueConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Default value to return when <see cref="IValueConverter.Convert(object?, Type, object?, CultureInfo?)"/> throws an <see cref="Exception"/>.
|
||||
|
@ -115,9 +118,11 @@ public abstract class BaseConverter<TFrom, TTo> : ValueConverterExtension, IComm
|
|||
public abstract TFrom DefaultConvertBackReturnValue { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
||||
public Type FromType { get; } = typeof(TFrom);
|
||||
|
||||
/// <inheritdoc/>
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
||||
public Type ToType { get; } = typeof(TTo);
|
||||
|
||||
object? ICommunityToolkitValueConverter.DefaultConvertReturnValue => DefaultConvertReturnValue;
|
||||
|
@ -140,7 +145,7 @@ public abstract class BaseConverter<TFrom, TTo> : ValueConverterExtension, IComm
|
|||
public abstract TFrom ConvertBackTo(TTo value, CultureInfo? culture);
|
||||
|
||||
/// <inheritdoc/>
|
||||
object? ICommunityToolkitValueConverter.ConvertBack(object? value, Type targetType, object? parameter, CultureInfo? culture)
|
||||
object? ICommunityToolkitValueConverter.ConvertBack(object? value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type targetType, object? parameter, CultureInfo? culture)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -158,7 +163,7 @@ public abstract class BaseConverter<TFrom, TTo> : ValueConverterExtension, IComm
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
object? ICommunityToolkitValueConverter.Convert(object? value, Type targetType, object? parameter, CultureInfo? culture)
|
||||
object? ICommunityToolkitValueConverter.Convert(object? value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type targetType, object? parameter, CultureInfo? culture)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
|
||||
namespace CommunityToolkit.Maui.Converters;
|
||||
|
@ -7,7 +8,7 @@ namespace CommunityToolkit.Maui.Converters;
|
|||
/// </summary>
|
||||
/// <typeparam name="TFrom">Type of the input value</typeparam>
|
||||
/// <typeparam name="TTo">Type of the output value</typeparam>
|
||||
public abstract class BaseConverterOneWay<TFrom, TTo> : BaseConverter<TFrom, TTo>
|
||||
public abstract class BaseConverterOneWay<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TFrom, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TTo> : BaseConverter<TFrom, TTo>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public sealed override TFrom DefaultConvertBackReturnValue
|
||||
|
@ -27,7 +28,7 @@ public abstract class BaseConverterOneWay<TFrom, TTo> : BaseConverter<TFrom, TTo
|
|||
/// <typeparam name="TFrom">Type of the input value</typeparam>
|
||||
/// <typeparam name="TTo">Type of the output value</typeparam>
|
||||
/// <typeparam name="TParam">Type of parameter</typeparam>
|
||||
public abstract class BaseConverterOneWay<TFrom, TTo, TParam> : BaseConverter<TFrom, TTo, TParam>
|
||||
public abstract class BaseConverterOneWay<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TFrom, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TTo, TParam> : BaseConverter<TFrom, TTo, TParam>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public sealed override TFrom DefaultConvertBackReturnValue
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Globalization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
|
||||
namespace CommunityToolkit.Maui.Converters;
|
||||
|
||||
|
@ -12,7 +13,7 @@ public class BoolToObjectConverter : BoolToObjectConverter<object>
|
|||
/// <summary>
|
||||
/// Converts <see cref="bool"/> to object and vice versa.
|
||||
/// </summary>
|
||||
public class BoolToObjectConverter<TObject> : BaseConverter<bool, TObject?>
|
||||
public class BoolToObjectConverter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TObject> : BaseConverter<bool, TObject?>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override TObject? DefaultConvertReturnValue { get; set; } = default;
|
||||
|
|
|
@ -14,7 +14,7 @@ public sealed class CompareConverter : CompareConverter<IComparable, object>
|
|||
/// <summary>
|
||||
/// Converts an object that implements IComparable to an object or a boolean based on a comparison.
|
||||
/// </summary>
|
||||
public abstract class CompareConverter<TValue, TReturnObject> : BaseConverterOneWay<TValue, object> where TValue : IComparable
|
||||
public abstract class CompareConverter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TValue, TReturnObject> : BaseConverterOneWay<TValue, object> where TValue : IComparable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override object DefaultConvertReturnValue { get; set; } = new();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Globalization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
|
||||
namespace CommunityToolkit.Maui.Converters;
|
||||
|
||||
|
@ -20,11 +21,13 @@ public interface ICommunityToolkitValueConverter : IValueConverter
|
|||
/// <summary>
|
||||
/// Gets the <see cref="Type" /> this converter expects to <see cref="Convert" /> from or <see cref="ConvertBack" /> to.
|
||||
/// </summary>
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
||||
Type FromType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Type" /> this converter expects to <see cref="Convert" /> to or <see cref="ConvertBack" /> from.
|
||||
/// </summary>
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
||||
Type ToType { get; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -35,7 +38,7 @@ public interface ICommunityToolkitValueConverter : IValueConverter
|
|||
/// <param name="parameter">Optional Parameters</param>
|
||||
/// <param name="culture">Culture Info</param>
|
||||
/// <returns>The converted object</returns>
|
||||
new object? Convert(object? value, Type targetType, object? parameter, CultureInfo? culture);
|
||||
new object? Convert(object? value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type targetType, object? parameter, CultureInfo? culture);
|
||||
|
||||
/// <summary>
|
||||
/// Converts the object back to the outgoing values
|
||||
|
@ -45,13 +48,20 @@ public interface ICommunityToolkitValueConverter : IValueConverter
|
|||
/// <param name="parameter">Optional Parameters</param>
|
||||
/// <param name="culture">Culture Info</param>
|
||||
/// <returns>The object converted back</returns>
|
||||
new object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo? culture);
|
||||
new object? ConvertBack(object? value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type targetType, object? parameter, CultureInfo? culture);
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
object? IValueConverter.Convert(object? value, Type targetType, object? parameter, CultureInfo culture) =>
|
||||
#if NET8_0 // Should be fixed in .NET 9
|
||||
#pragma warning disable IL2092
|
||||
#endif
|
||||
object? IValueConverter.Convert(object? value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type targetType, object? parameter, CultureInfo culture) =>
|
||||
Convert(value, targetType, parameter, culture);
|
||||
|
||||
/// <inheritdoc />
|
||||
object? IValueConverter.ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
|
||||
object? IValueConverter.ConvertBack(object? value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type targetType, object? parameter, CultureInfo culture) =>
|
||||
ConvertBack(value, targetType, parameter, culture);
|
||||
#if NET8_0
|
||||
#pragma warning restore IL2092
|
||||
#endif
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.Globalization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
|
||||
namespace CommunityToolkit.Maui.Converters;
|
||||
|
||||
|
@ -6,7 +7,7 @@ namespace CommunityToolkit.Maui.Converters;
|
|||
public sealed class IsInRangeConverter : IsInRangeConverter<IComparable, object>;
|
||||
|
||||
/// <summary>Converts the incoming value to a <see cref="bool"/> indicating whether or not the value is within a range.</summary>
|
||||
public abstract class IsInRangeConverter<TValue, TReturnObject> : BaseConverterOneWay<TValue, object> where TValue : IComparable
|
||||
public abstract class IsInRangeConverter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TValue, TReturnObject> : BaseConverterOneWay<TValue, object> where TValue : IComparable
|
||||
{
|
||||
/// <summary>
|
||||
/// Bindable property for <see cref="FalseObject"/>
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace CommunityToolkit.Maui.Converters;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace CommunityToolkit.Maui.Converters;
|
||||
|
||||
/// <summary>
|
||||
/// Converts an incoming value using all of the incoming converters in sequence.
|
||||
|
@ -9,10 +11,15 @@ public class MultiConverter : List<ICommunityToolkitValueConverter>, ICommunityT
|
|||
|
||||
object? ICommunityToolkitValueConverter.DefaultConvertBackReturnValue => throw new NotSupportedException($"{nameof(ICommunityToolkitMultiValueConverter)} does not implement {nameof(ICommunityToolkitValueConverter.DefaultConvertBackReturnValue)}");
|
||||
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
||||
Type ICommunityToolkitValueConverter.FromType => throw new NotSupportedException($"{nameof(ICommunityToolkitMultiValueConverter)} does not implement {nameof(ICommunityToolkitValueConverter.FromType)}");
|
||||
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
|
||||
Type ICommunityToolkitValueConverter.ToType => throw new NotSupportedException($"{nameof(ICommunityToolkitMultiValueConverter)} does not implement {nameof(ICommunityToolkitValueConverter.ToType)}");
|
||||
|
||||
#if NET8_0 // Should be fixed in .NET 9
|
||||
#pragma warning disable IL2092
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Uses the incoming converters to convert the value.
|
||||
/// </summary>
|
||||
|
@ -21,7 +28,7 @@ public class MultiConverter : List<ICommunityToolkitValueConverter>, ICommunityT
|
|||
/// <param name="parameter">Parameter to pass into subsequent converters.</param>
|
||||
/// <param name="culture">The culture to use in the converter.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public object? Convert(object? value, Type targetType, object? parameter, System.Globalization.CultureInfo? culture)
|
||||
public object? Convert(object? value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type targetType, object? parameter, System.Globalization.CultureInfo? culture)
|
||||
=> parameter is IList<MultiConverterParameter> parameters
|
||||
? this.Aggregate(value, (current, converter) => converter.Convert(current, converter.ToType,
|
||||
parameters.FirstOrDefault(x => x.ConverterType == converter.GetType())?.Value, culture))
|
||||
|
@ -35,6 +42,9 @@ public class MultiConverter : List<ICommunityToolkitValueConverter>, ICommunityT
|
|||
/// <param name="parameter">N/A</param>
|
||||
/// <param name="culture">N/A</param>
|
||||
/// <returns>N/A</returns>
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, System.Globalization.CultureInfo? culture)
|
||||
public object? ConvertBack(object? value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type targetType, object? parameter, System.Globalization.CultureInfo? culture)
|
||||
=> throw new NotSupportedException("Impossible to revert to original value. Consider setting BindingMode to OneWay.");
|
||||
#if NET8_0 // Should be fixed in .NET 9
|
||||
#pragma warning restore IL2092
|
||||
#endif
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using CommunityToolkit.Maui.Views;
|
||||
|
||||
// Using root CommunityToolkit.Maui namespace so these extension methods
|
||||
|
@ -24,7 +25,7 @@ public static class ServiceCollectionExtensions
|
|||
/// <remarks>Developers are still responsible for assigning the injected instance of
|
||||
/// <typeparamref name="TViewModel" />
|
||||
/// to the BindingContext property of <typeparamref name="TView" />.</remarks>
|
||||
public static IServiceCollection AddTransient<TView, TViewModel>(this IServiceCollection services)
|
||||
public static IServiceCollection AddTransient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TView, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TViewModel>(this IServiceCollection services)
|
||||
where TView : BindableObject
|
||||
where TViewModel : class, INotifyPropertyChanged
|
||||
{
|
||||
|
@ -43,7 +44,7 @@ public static class ServiceCollectionExtensions
|
|||
/// <see cref="INotifyPropertyChanged"/></typeparam>
|
||||
/// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
public static IServiceCollection AddTransientPopup<TPopupView, TPopupViewModel>(this IServiceCollection services)
|
||||
public static IServiceCollection AddTransientPopup<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TPopupView, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TPopupViewModel>(this IServiceCollection services)
|
||||
where TPopupView : Popup
|
||||
where TPopupViewModel : INotifyPropertyChanged
|
||||
{
|
||||
|
@ -69,7 +70,7 @@ public static class ServiceCollectionExtensions
|
|||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
/// <remarks>Developers are still responsible for assigning the injected instance of <typeparamref name="TViewModel" />
|
||||
/// to the BindingContext property of <typeparamref name="TView" />.</remarks>
|
||||
public static IServiceCollection AddTransientWithShellRoute<TView, TViewModel>(this IServiceCollection services, string route, RouteFactory? factory = null)
|
||||
public static IServiceCollection AddTransientWithShellRoute<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TView, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TViewModel>(this IServiceCollection services, string route, RouteFactory? factory = null)
|
||||
where TView : NavigableElement
|
||||
where TViewModel : class, INotifyPropertyChanged
|
||||
{
|
||||
|
@ -89,7 +90,7 @@ public static class ServiceCollectionExtensions
|
|||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
/// <remarks>Developers are still responsible for assigning the injected instance of <typeparamref name="TViewModel" />
|
||||
/// to the BindingContext property of <typeparamref name="TView" />.</remarks>
|
||||
public static IServiceCollection AddSingleton<TView, TViewModel>(this IServiceCollection services)
|
||||
public static IServiceCollection AddSingleton<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TView, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TViewModel>(this IServiceCollection services)
|
||||
where TView : BindableObject
|
||||
where TViewModel : class, INotifyPropertyChanged
|
||||
{
|
||||
|
@ -115,7 +116,7 @@ public static class ServiceCollectionExtensions
|
|||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
/// <remarks>Developers are still responsible for assigning the injected instance of <typeparamref name="TViewModel" />
|
||||
/// to the BindingContext property of <typeparamref name="TView" />.</remarks>
|
||||
public static IServiceCollection AddSingletonWithShellRoute<TView, TViewModel>(this IServiceCollection services, string route, RouteFactory? factory = null)
|
||||
public static IServiceCollection AddSingletonWithShellRoute<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TView, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TViewModel>(this IServiceCollection services, string route, RouteFactory? factory = null)
|
||||
where TView : NavigableElement
|
||||
where TViewModel : class, INotifyPropertyChanged
|
||||
{
|
||||
|
@ -135,7 +136,7 @@ public static class ServiceCollectionExtensions
|
|||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
/// <remarks>Developers are still responsible for assigning the injected instance of <typeparamref name="TViewModel" />
|
||||
/// to the BindingContext property of <typeparamref name="TView" />.</remarks>
|
||||
public static IServiceCollection AddScoped<TView, TViewModel>(this IServiceCollection services)
|
||||
public static IServiceCollection AddScoped<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TView, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TViewModel>(this IServiceCollection services)
|
||||
where TView : BindableObject
|
||||
where TViewModel : class, INotifyPropertyChanged
|
||||
{
|
||||
|
@ -161,7 +162,7 @@ public static class ServiceCollectionExtensions
|
|||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
/// <remarks>Developers are still responsible for assigning the injected instance of <typeparamref name="TViewModel" />
|
||||
/// to the BindingContext property of <typeparamref name="TView" />.</remarks>
|
||||
public static IServiceCollection AddScopedWithShellRoute<TView, TViewModel>(this IServiceCollection services, string route, RouteFactory? factory = null)
|
||||
public static IServiceCollection AddScopedWithShellRoute<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TView, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TViewModel>(this IServiceCollection services, string route, RouteFactory? factory = null)
|
||||
where TView : NavigableElement
|
||||
where TViewModel : class, INotifyPropertyChanged
|
||||
{
|
||||
|
@ -176,7 +177,7 @@ public static class ServiceCollectionExtensions
|
|||
/// <param name="route">Route at which this page will be registered within Shell routing.</param>
|
||||
/// <param name="factory">RouteFactory to be used while creating the <see cref="NavigableElement"/>
|
||||
/// for the route. Defaults to TypeRouteFactory.</param>
|
||||
static void RegisterShellRoute<TView>(string route, RouteFactory? factory = null)
|
||||
static void RegisterShellRoute<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TView>(string route, RouteFactory? factory = null)
|
||||
where TView : NavigableElement
|
||||
{
|
||||
if (factory is null)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using CommunityToolkit.Maui.Converters;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using CommunityToolkit.Maui.Converters;
|
||||
|
||||
namespace CommunityToolkit.Maui.Extensions;
|
||||
|
||||
|
@ -11,7 +12,7 @@ public abstract class ValueConverterExtension : BindableObject, IMarkupExtension
|
|||
|
||||
private protected static bool IsNullable<T>() => IsNullable(typeof(T));
|
||||
|
||||
private protected static bool IsValidTargetType<TTarget>(in Type targetType, bool shouldAllowNullableValueTypes)
|
||||
private protected static bool IsValidTargetType<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TTarget>([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] in Type targetType, bool shouldAllowNullableValueTypes)
|
||||
{
|
||||
if (IsConvertingToString(targetType) && CanBeConvertedToString())
|
||||
{
|
||||
|
@ -54,7 +55,7 @@ public abstract class ValueConverterExtension : BindableObject, IMarkupExtension
|
|||
}
|
||||
}
|
||||
|
||||
private protected static void ValidateTargetType<TTarget>(Type targetType, bool shouldAllowNullableValueTypes)
|
||||
private protected static void ValidateTargetType<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TTarget>([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type targetType, bool shouldAllowNullableValueTypes)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(targetType);
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using CommunityToolkit.Maui.Core;
|
||||
using CommunityToolkit.Maui.Views;
|
||||
using Microsoft.Maui.Controls.Platform;
|
||||
|
@ -35,7 +36,7 @@ public class PopupService : IPopupService
|
|||
?? throw new InvalidOperationException("Could not locate IServiceProvider");
|
||||
}
|
||||
|
||||
internal static void AddTransientPopup<TPopupView, TPopupViewModel>(IServiceCollection services)
|
||||
internal static void AddTransientPopup<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TPopupView, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TPopupViewModel>(IServiceCollection services)
|
||||
where TPopupView : IPopup
|
||||
where TPopupViewModel : INotifyPropertyChanged
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче