MAUI 迁移指南

前言

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

  • 单个代码库演变

  • 启动配置演变

  • 统一资源管理

  • 依赖注入

  • 隐式using 指令

  • Essentials合并

  • 全新命名空间

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

单个代码库演变

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

  • MyApp(共享类库): 用于编写非特定平台的业务逻辑实现代码

  • MyApp.Android(原生安卓应用):包含Android平台的特定配置、资源、程序集相关。

  • MyApp.iOS(原生安卓应用):包含IOS平台的特定配置、资源、程序集相关。

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

下面, 则演示了一个MAUI的典型应用的项目结果, 仅包含了一个项目。
889ede808fc199ab09171ad2de34fb2e.png
MAUI 应用的项目包含 一个 Platform 文件夹,每个子文件夹都表示 .NET MAUI 可以面向的平台
9d25332bb55dc2759f026b8a5f8d0d7e.png
在生成时,生成系统仅在为该特定平台生成时包含每个文件夹中的代码。例如,在为 Android 生成平台时Android文件夹中的文件>将内置到应用包中,但其他平台文件夹中的文件不会。

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

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

启动配置演变

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

protected override void OnCreate(Bundle savedInstanceState){base.OnCreate(savedInstanceState);//初始化Xamarin.FormsXamarin.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.Formsglobal::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中, 每个项目都包含各自的资源文件, 大多数情况下, 我们会重复定义几组相同的资源(字体、样式、图像)在对应的平台
0b69b7809d32bbc31dd1b7c51814de5e.png

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

依赖注入

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

在具体的实现类当中, 我们还需要程序集级别的特性标记, 以便于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);PLAINTEXT复制全屏

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/286312.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ivx动效按钮 基础按钮制作 01

一、准备工作 首先创建一个相对定位应用&#xff1a; 接着创建一个页面&#xff1a; 随后我们切换一下屏幕&#xff0c;更改为 PC 端 web&#xff0c;因为手机移动端一般是没有鼠标悬浮事件的&#xff1a; 为了使按钮显示方便观察&#xff0c;我们设置水平和垂直对其为居中…

android中xml tools属性详解

第一部分 安卓开发中&#xff0c;在写布局代码的时候&#xff0c;ide可以看到布局的预览效果。但是有些效果则必须在运行之后才能看见&#xff0c;比如这种情况&#xff1a;TextView在xml中没有设置任何字符&#xff0c;而是在activity中设置了text。因此为了在ide中预览效果&a…

C语言试题十九之根据以下公式求p的值,结果由函数值带回。M与n为两个正整数,且要求m>n。 p=m!/n!(m-n)!

📃个人主页:个人主页 🔥系列专栏:C语言试题200例目录 💬推荐一款刷算法、笔试、面经、拿大公司offer神器 👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 编写函数f…

Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析

在前面一篇文章Android系统匿名共享内存Ashmem&#xff08;Anonymous Shared Memory&#xff09;驱动程序源代码分析中&#xff0c;我们系统地介绍了Android系统匿名共享内存的实现原理&#xff0c;其中着重介绍了它是如何辅助内存管理系统来有效地管理内存的&#xff0c;在再前…

转帖-Linux学习(Find命令使用实例)

为什么80%的码农都做不了架构师&#xff1f;>>> find / -name httpd.conf find / -name access_log 2>/dev/null find /etc -name *srm* find / -amin -10 # 查找在系统中最后10分钟访问的文件 find / -atime -2 # 查找在系统中最后48小时访问的文件 find / -mm…

Landsat中国西北地区行列号Shapefile图层对照(附行列号Shapefile下载)

GISer们,在下载Landsat卫星影像数据时,你还在为研究区的影响行列号犯愁吗?你还在苦苦对照图片吗?你Out了!重磅来了,本文提供了中国西北地区的Shapefile格式的矢量图层,和你的研究区叠在一起,是不是可以很快找出你想要的行列号呢? 《中国区域Modis行列号,Landsat条带…

|洛谷|动态规划|P1164 小A点菜

http://www.luogu.org/record/lists?pidP1164 01背包方案数#include<cstdio> #include<algorithm> #include<cstring> #define ms(i,j) memset(i,j, sizeof i); using namespace std; int n,m; int a[105]; int f[10005]; int main() {scanf("%d%d&quo…

MAUI 入门教程系列(1.框架简介)

前言在2020年5月, 微软宣布了MAUI跨平台框架, MAUI 是Xamarin.Forms演变而来, 这也就意味着, 如果你原来具备Xamarin.Forms开发经验, 你可以流畅的过渡到MAUI开发当中。原本于2021年底发布的MAUI正式版被推迟到了2022年5月底发布。现在, 你目前可以通过安装VS2022 预览版进行安…

ivx动效按钮 基础按钮制作 02

本节示例&#xff1a; 一、特效块的制作 在上一节中制作了一个可以增加动效的自定义按钮后&#xff0c;这一节通过这个行按钮对其进行特效制作。 在行按钮中的绝对定位中&#xff0c;我们创建一个行&#xff0c;命名为移入&#xff0c;接下来我们做一个移入动效&#xff1a…

C语言试题二十之利用以下的简单迭代方法求方程cos(x)-x=0的一个实根。

📃个人主页:个人主页 🔥系列专栏:C语言试题200例目录 💬推荐一款刷算法、笔试、面经、拿大公司offer神器 👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 编写函数fu…

最新Modis影像数据下载完整流程---以MOD13Q1 NDVI数据下载为例(2020年12月2日更新)

本文详细讲解Modis数据的下载流程,以MOD13Q1影像为例,该数据为16天合成的空间分辨率为250m的NDVI产品,原始数据的投影为正弦曲线投影。 Modis数据MRT和ArcGIS处理方法集锦: 1.《ArcGIS10.8完美实现MODIS NDVI数据格式转换和投影变换》 2.《重磅!ArcGIS10.8 Python代码批量…

解决夜神模拟器无法联机调试 adb server version (**) doesn't match this client (**); killing...

前言 最新下了个最新版的夜神模拟器&#xff0c;然后adb devices发现连不上模拟器了&#xff0c;报adb server version (**) doesnt match this client (##); killing... 从报错信息看是adb版本不匹配导致的&#xff0c;接下来讲如何解决这个问题 环境&#xff1a; 夜神模拟器…

WCF分布式开发常见错误(25):The certificate 'CN=WCFHTTPS' must have a private key

在准备WCF安全开发实践编程系列文章的时候&#xff0c;制作证书出现这个问题。The certificate CNWCFHTTPS must have a private key that is capable of key exchange. The process must have access rights for the private key.证书必须有一个可以交换密钥的私钥&#xff0c…

lintcode二叉树的锯齿形层次遍历 (双端队列)

题目链接&#xff1a; http://www.lintcode.com/zh-cn/problem/binary-tree-zigzag-level-order-traversal/ 二叉树的锯齿形层次遍历 给出一棵二叉树&#xff0c;返回其节点值的锯齿形层次遍历&#xff08;先从左往右&#xff0c;下一层再从右往左&#xff0c;层与层之间交替进…

C语言试题二十一之定义n×n的二维数组编写函数 function(int a[][n])功能是:使数组左下半三角元素中的值全部置成0。

📃个人主页:个人主页 🔥系列专栏:C语言试题200例目录 💬推荐一款刷算法、笔试、面经、拿大公司offer神器 👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 定义了nn的…

【前端就业课 第二阶段】CSS 零基础到实战(02)列表

整个前端学习路线 以下路线为 CSDN C认提供&#xff1a; 如果想 快点搞完 并且 就业 可以选择C认证&#xff0c;C认证还可以 内推、招聘会 &#xff0c;所以如果在校生想要稳一点&#xff0c;就可以选择C认证或者超级实习生计划&#xff0c;贼稳&#xff01; 链接在这PC端&…

【专升本计算机】甘肃省2020年专升本计算机测试题

文章目录 第一部分 公共基础部分第二部分 数据库部分(文史财经类)第三部分 C语言部分(理工农医类)第四部分 综合部分第一部分 公共基础部分 一、单项选择(90题,每题1分,共90分) 世界上第一台电子计算机诞生于( )年。 A. 1956 B. 1946 C. 1944 D. 1940目前,第二代计…

Docker Eats Disk?

背景介绍下午 5:30&#xff0c;差不多到点打卡下班&#xff0c;准备好零食饮料&#xff0c;放松一下准备下班&#xff0c;然后...CI 构建失败&#xff0c;经典的一幕&#xff01;&#xff01;&#xff01;无法从镜像仓库拉取镜像&#xff0c;docker 正常运行&#xff0c;为什么…

C#网络编程(订立协议和发送文件) - Part.4

转载自&#xff1a;http://www.tracefact.net/CSharp-Programming/Network-Programming-Part4.aspx 文件传输 前面两篇文章所使用的范例都是传输字符串&#xff0c;有的时候我们可能会想在服务端和客户端之间传递文件。比如&#xff0c;考虑这样一种情况&#xff0c;假如客户端…

Android Studio怎么设置悬浮提示文字框显示函数

[摘要]AndroidStudio函数悬浮提示文字框设置方法一&#xff1a;AndroidStudio在默认情况下是不会和Eclipse那样&#xff0c;鼠标移动到一个类或... Android Studio函数悬浮提示文字框设置方法一&#xff1a; Android Studio在默认情况下是不会和Eclipse那样&#xff0c;鼠标移…