• MAUI 迁移指南(1)


    前言

    为了能够让大家更好的理解全新的MAUI框架, 那么本次迁移指南主要给大家讲解从Xamarin.Forms升级到MAUI带来了哪些全新的变化, 下面将围绕一下几点给大家重点介绍。

    • 单个代码库演变
    • 启动配置演变
    • 统一资源管理
    • 依赖注入
    • 隐式using 指令
    • Essentials合并
    • 全新命名空间

    您仅需要具备Xamarin.Forms的一些基础概念

    单个代码库演变

    如下,演示了一个Xamarin.Forms典型应用的项目结构, 包含了一个共享类库以及2个原生平台的应用(Android/IOS)。

    • MyApp(共享类库): 用于编写非特定平台的业务逻辑实现代码
    • MyApp.Android(原生安卓应用):包含Android平台的特定配置、资源、程序集相关。
    • MyApp.iOS(原生安卓应用): 包含IOS平台的特定配置、资源、程序集相关。

    如果您的应用选择Windows平台, 则会多一个UWP项目选项, 类似,这仅仅是针对UWP平台的相关配置。

    下面, 则演示了一个MAUI的典型应用的项目结果, 仅包含了一个项目。

    MAUI 应用的项目包含 一个 Platform 文件夹,每个子文件夹都表示 .NET MAUI 可以面向的平台

    在生成时,生成系统仅在为该特定平台生成时包含每个文件夹中的代码。 例如,在为 Android 生成平台时Android文件夹中的文件>将内置到应用包中,但其他平台文件夹中的文件不会。

    有了单代码库的支持, 我们不再需要单独维护多个平台的项目, 重复的SDK引用, 资源文件定义等。

    关于基于多目标的配置, 可参考 MAUI 中配置多目标

    启动配置演变

    在Xamarin.Forms当中, 无论是我们启动Android还是IOS项目, 我们都需要在启动之前初始化Xamarin.Forms框架。
    Android

            protected override void OnCreate(Bundle savedInstanceState)
            {
                base.OnCreate(savedInstanceState);
                //初始化Xamarin.Forms
                Xamarin.Essentials.Platform.Init(this, savedInstanceState);
                global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
                LoadApplication(new App());
            }
    

    IOS中

            public override bool FinishedLaunching(UIApplication app, NSDictionary options)
            {
                //初始化Xamarin.Forms
                global::Xamarin.Forms.Forms.Init();
                LoadApplication(new App());
    
                return base.FinishedLaunching(app, options);
            }
    

    整个初始化过程中, 我们是无法进行配置的, 例如: 扫描程序集配置容器服务、导出字体、加载默认的控件渲染器、平台绑定等。 这也就意味着, 对于Xamarin.Forms而言,
    大多数功能都是按照约定配置, 无法进行自定义, 以及服务大都是扫描程序集进行反射加载的。

    在MAUI当中, 使用了类似通用主机结构来初始化 .NET MAUI 应用程序。这将为用户提供非常微软的体验,并且让许多代码符合 ASP.NET Core 范式。

    public static MauiApp CreateMauiApp()
    	{
    		var builder = MauiApp.CreateBuilder();
    		builder
    			.UseMauiApp<App>()
    			.ConfigureFonts(fonts =>
    			{
    				fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
    				fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
    			});
    
    		return builder.Build();
    	}
    

    在默认情况下, 每个单独的平台都会调用 CreateMauiApp 来构建应用程序的服务依赖。

    统一资源管理

    在Xamarin.Forms中, 每个项目都包含各自的资源文件, 大多数情况下, 我们会重复定义几组相同的资源(字体、样式、图像)在对应的平台

    MAUI单项目解决了这个问题, 在 Resources 文件夹当中, 包含了所有的资源文件定义。

    依赖注入

    在Xamarin.Forms中,如果我们想要使用依赖注入,来实现特定平台的实现, 首先需要在共享类库中定义标准接口, 然后每个平台单独实现一遍。

    在具体的实现类当中, 我们还需要程序集级别的特性标记, 以便于Xamarin.Forms初始化的过程中能够扫描程序集并且加载到容器当中。

    [assembly: Xamarin.Forms.Dependency(typeof(LocalService))]
    namespace MyApp.Droid
    {
        public class LocalService : ILocalService
        {
            public void SetValue(string key, object value)
            {
    
            }
        }
    }
    

    获取容器服务的方式, 则可以通过DependencyService的静态方法获取。

     var localService= DependencyService.Get<ILocalService>();
    

    同样, 针对字体的访问, 也是通过扫描程序集的方式加载

    [assembly: ExportFont("iconfont.ttf", Alias = "iconfont")]
    

    那么, 在MAUI当中, 通过通用主机的形式, 提供了容器可以进行自定义配置服务。

     public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    //注入字体
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                });
    
            //注入服务
            builder.Services.AddScoped<ILocalService, LocalService>(); 
            return builder.Build();
        }
    

    是不是很轻松? 不仅仅非常直观, 也大大的提高的开发效率以及性能

    隐式using 指令

    有了global using , 我们无需在多个类当中重复定义命名空间, 只需要一句 global using, 从此别的类当中会自动引用。

    global using System;
    global using System.Threading;
    global using System.Linq;
    global using System.ComponentModel;
    

    针对一些非常常见的命名空间, 我们都可以使用 global using。

    • Essentials合并
      Xamarin.Forms时期, 我们使用Essentials它是单独进行nuget分发以及维护, 在配置的时候, 我们也需要单独的初始化代码。
    Xamarin.Essentials.Platform.Init(this, savedInstanceState);
    

    MAUI则将Essentials全部融合到了MAUI项目当中, 命名控件则是 Microsoft.MAUI下, 例如访问设备。

    using Microsoft.Maui.Devices
    
    • 全新命名空间
      Xamarin.Forms 当中我们使用的 using Xamarin.Forms 变成了 using Microsoft.Maui 相关。

    • 性能改进
      性能也带来了很大的改进, 可参考文章: .NET MAUI 中的性能改进

    • 关于更多
      1.事件处理程序
      2.兼容现有的渲染器模式
      后面再接着说...

  • 相关阅读:
    Thread.Sleep(0)的作用
    javascript form提交 不执行onsubmit事件解决方案
    获取控件生成的html
    (诡异事件)iframe标签后面的alert不执行
    数据重复插入的问题
    aspnetpager bug
    晒一下我的数据访问层接口
    Jquery.ajax不能解析json对象,报Invalid JSON错误的原因和解决方法(转)
    火狐对ajax的onreadystatechange与IE的不同。
    一个命名的问题把我给折腾的
  • 原文地址:https://www.cnblogs.com/zh7791/p/16355705.html
Copyright © 2020-2023  润新知