Xamarin.Forms的框架有一处设计我始终想不明白

tmp00000 UID.995403
2016-07-30 发表

了解过Xamarin的开发人员应该知道Xamarin能编写一次,到处运行。
作为可移植类库和平台特定类库被使用的Xamarin在UWP上由以下类库组成:

Xamarin.Forms.Platform.dll
^
|
Xamarin.Forms.Core.dll
^ ^
| |
Xamarin.Forms.Platform.UAP.dll Xamarin.Forms.Xaml.dll

我看了Xamarin.Forms.Platform.dll的内容,搞不懂这个类库是干什么用的。
首先,它的 internal(在Visual Basic 为 Friend)内容只对Xamarin.Forms.Core可见。
使用反编译软件查看它的源码,里面有一堆 internal(在Visual Basic 为 Friend) _XxxxxRenderer 类,它们都继承Object,而且都是空的。我叫它们“空壳类”。
还有个与众不同的 静态类(在Visual Basic 为 模块) Loader ,里面除了空白的Load(),什么都没有。
以 _ActivityIndicatorRenderer 类为例。
它在Xamarin.Forms.Core.dll中的ActivityIndicator类由RenderWithAttribute使用。
这个RenderWith在Registrar<TRegistrable> where T:class ( 在Visual Basic 为 Registrar(Of TRegistrable As Class) ) 中被注册
这种空壳类注册到那里之后在多个地方被访问。最显眼的地方是Platform.CreateRenderer(VisualElement),而这个方法在VisualElementPackager被调用。
最后公开出来的是Xamarin.Forms.Platform.UAP.VisualElementRenderer`2.SetElement(VisualElement)。
假设代码运行的时候用到了那些空壳的类,它们被某些反射代码注册到Registrar`1里面。然而,注册的时候可能会发生异常,因为注册的时候注册用的字典根本就没初始化。要初始化的话必须用反射。然而我根本没找到哪里的反射代码在初始化那个字典。
从这个方向看我完全看不出来那些空壳类在运行的时候有什么实际的作用。
那我从反方向看。我在那个UAP的类库找到了ActivityIndicatorRenderer类。UAP的类库本身带有ExportRenderer这样的特性,能够关联Core里面的类型与平台实现的类型。这些Renderer类最终被注册到Core中的非泛型的Registrar类里。这一切看起来合情合理,因为注册平台实现到跨平台的类库里,然后用反射初始化对象,整个过程非常自然。从这个方向我根本没看到Xamarin.Forms.Platform里面的那些空壳类有什么用。

敬告:
为防止不可控的内容风险,本站已关闭新用户注册,新贴的发表及评论;
你现在看到的内容只是互联网用户曾经发表的言论快照,仅用于老用户留存纪念,且仅与科技行业相关,全部内容不代表本站观点及立场;
本站重新开放前已针对包括用户隐私、版权保护、信息安全、国家政策在内的各种互联网法律法规要求,执行了隐患内容的自查、屏蔽和删除;
本站目前所属个人主体,未有任何盈利安排与计划,且与原WFUN.COM所属公司不存在任何关联关系;
如果本帖内容或者相关资源侵犯到您的合法权益,或者您认为存在问题,那么请您务必点此举报或投诉!
全部回复:
tmp00000 UID.995403
2016-07-30 回复

我能猜想到的结果只有一个:Xamarin.Forms.Platform.dll里面的类是用来做测试或者是用来生成代码的。自动化的程序集 检查/代码生成 工具用反射加载这个类库,检查/生成 其它类库。不过,做这种检查/代码生成 为什么要新建一个类库呢?用资源文件不好吗?

单身****是狗 UID.1144139
2016-07-30 回复

虽然看不懂,但是msdn可能是个好地方可以去看下,有可能一些api一辈子用不到,但他就是存在

tmp00000 UID.995403
2016-07-30 使用 Lumia 1520 回复

Quote单身狗不是狗 发表于 2016-7-30 00:14
虽然看不懂,但是msdn可能是个好地方可以去看下,有可能一些api一辈子用不到,但他就是存在 ...


那里没有相关的东西。连xamarin的API介绍都没有。

尘世难 UID.997613
2016-07-30 使用 Lumia 925 回复

不明觉厉,帮顶

重头儿再来 UID.356529
2016-07-30 回复

楼主,关于Xamarin.Forms 有一本很厚的pdf资料,不知楼主是否拥有?
另外,想请教一下,Xamarin.Forms只是关于UI方面的编程吧?

tmp00000 UID.995403
2016-07-30 使用 Lumia 1520 回复

Quote重头儿再来 发表于 2016-7-30 09:26
楼主,关于Xamarin.Forms 有一本很厚的pdf资料,不知楼主是否拥有?
另外,想请教一下,Xamarin.Forms只是 ...


那个资料是告诉我们这个框架怎么用的,没讲它是怎么设计的

tmp00000 UID.995403
2016-07-30 回复

本帖最后由 tmp00000 于 2016-7-31 13:52 编辑

看样子这里应该没人知道答案

wcavell UID.34926
2016-07-31 回复

Quote***链接停止解析***
看样子这里应该每人知道答案


我除了装逼,啥都不懂,叫我怎么回答。
说来奇怪,微软也经常弄一些空的接口,不知道他想干啥

重头儿再来 UID.356529
2016-07-31 回复

Quote***链接停止解析***
看样子这里应该每人知道答案


楼主能推荐一些可能知道答案的地方嘛?

tmp00000 UID.995403
2016-07-31 回复

Quote重头儿再来 发表于 2016-7-31 11:42
楼主能推荐一些可能知道答案的地方嘛?


我试试Xamarin Forum。那里的人虽然不用中文,但比这里的人更了解Xamarin。

vbfool UID.352791
2016-08-01 回复

按说这不就是用来抽象的么?为了让你在不同平台上有相同的库来用,这种跨平台的库,设计方式大多都是这样的吧,一个Wrapper式的库顶在最上边。

tmp00000 UID.995403
2016-08-01 回复

Quotevbfool 发表于 2016-8-1 09:57
按说这不就是用来抽象的么?为了让你在不同平台上有相同的库来用,这种跨平台的库,设计方式大多都是这样的 ...


终于等到对架构设计有研究的网友了。
通过反编译 Xamarin 的类库,我发现 Xamarin.Forms.Platform.UAP.dll 没有引用 Xamarin.Forms.Platform.dll。观察代码后能确认 Xamarin.Forms.Platform.UAP.dll 也没有用反射加载 Xamarin.Forms.Platform.dll。
Xamarin 应用初始化的时候 Xamarin.Forms.Core.dll 用反射把 View 到 Xamarin.Forms.Platform.UAP.dll 里面导出的 Renderer 类型的映射关系放到了一个字典里面。初始化 View 的时候用反射初始化 Renderer。这个过程并不需要使用 Xamarin.Forms.Platform.dll 中的任何成员让它们作为包装器。

vbfool UID.352791
2016-08-01 回复

Quote***链接停止解析***
终于等到对架构设计有研究的网友了。
通过反编译 Xamarin 的类库,我发现 Xamarin.Forms.Platform.UAP.dl ...


如果这么搞,你删掉这个dll呢?
说实话我还没碰过Xamarin.Forms,只能根据你说的东西来猜测。

tmp00000 UID.995403
2016-08-01 回复

Quotevbfool 发表于 2016-8-1 16:21
如果这么搞,你删掉这个dll呢?
说实话我还没碰过Xamarin.Forms,只能根据你说的东西来猜测。 ...


删掉的话应用直接闪退

vbfool UID.352791
2016-08-02 回复

Quote***链接停止解析***
删掉的话应用直接闪退


如果这样的话,那么它要么是部分内容没法编译出来,要么是个摆设式的壳,因为在其它平台上也需要类似的抽象,但是有实际内容。

tmp00000 UID.995403
2016-08-05 回复

Quotevbfool 发表于 2016-8-2 09:58
如果这样的话,那么它要么是部分内容没法编译出来,要么是个摆设式的壳,因为在其它平台上也需要类似的抽 ...


我从GitHub下载了Xamarin.Forms的源码。 看了代码后,能够确定 Xamarin.Forms.Platform.dll 中的Loader永远不会被调用,并且其它类确实是空的。空的类只被引用到RenderWithAttribute。顺着这个线索,我追踪到了 Xamarin.Forms.Platform.iOS.Classic.dll。看来这个项目里有些东西还没与其它平台统一,使用这些虚假的渲染器阻止某些运行时异常的发生。
***图片停止解析***

命苦****00 UID.335824
2016-08-24 回复

我觉的可能测试的时候 出现了耦合性的bug 才做成这样的吧

bai****hua UID.2867857
2016-11-19 回复

闲来无事,回你一下 :-D

这个东西非常重要,它是负责把xamarin.forms中定义的各种控件映射到本地平台控件的一个接口文件,各个平台还需要实现具体的renderer。可以把xamarin.forms的源代码下载下来看一下就明白了。

tmp00000 UID.995403
2016-11-19 回复

Quotebaijianhua 发表于 2016-11-19 21:07
闲来无事,回你一下 :-D

这个东西非常重要,它是负责把xamarin.forms中定义的各种控件映射到本地平台控件 ...


我看源码了。那个文件是个历史遗留问题。在UWP根本不会使用里面的任何类。唯一有关联的是Classic iOS的类库。它还用来做测试的桩模块。

hihahuha UID.17731
2017-09-18 回复

楼主学得好高深,我虽然在应用它,但这些完全不懂.
借楼请叫一个问题,xamarin里有办法通过反射实现动态加载dll吗?

tmp00000 UID.995403
2017-09-18 回复

Quotehihahuha 发表于 2017-9-18 05:28
楼主学得好高深,我虽然在应用它,但这些完全不懂.
借楼请叫一个问题,xamarin里有办法通过反射实现动态加 ...


Xamarin.Android 可以,其余有一定难度

artfly08 UID.2900999
2018-06-26 使用 Lumia 950 XL 回复

支持开发者

artfly08 UID.2900999
2018-06-26 使用 Lumia 950 XL 回复

尊重,敬佩开发者,
总感觉开发者所工作枯燥,严谨,要耐得住寂寞,
佩服。

artfly08 UID.2900999
2018-07-14 使用 Lumia 950 XL 回复

太专业,支持

本站使用Golang构建,点击此处申请开源鄂ICP备18029942号-4联系站长投诉/举报