Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6658142
  • 博文数量: 915
  • 博客积分: 17977
  • 博客等级: 上将
  • 技术积分: 8846
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-26 09:59
个人简介

一个好老好老的老程序员了。

文章分类

全部博文(915)

文章存档

2022年(9)

2021年(13)

2020年(10)

2019年(40)

2018年(88)

2017年(130)

2015年(5)

2014年(12)

2013年(41)

2012年(36)

2011年(272)

2010年(1)

2009年(53)

2008年(65)

2007年(47)

2006年(81)

2005年(12)

分类: Android平台

2018-07-15 15:29:53

依赖服务和可移植类库

PlatInfoSap2程序中说明的技术是否可以在具有可移植类库的解决方案中实现? 起初,它似乎不可能。 虽然应用程序项目一直调用库,但是除了事件或回调函数的上下文之外,库通常不能调用应用程序。 PCL与独立于设备的.NET版本捆绑在一起,只能在其自身或其他可能引用的PCL中执行代码。
但是等待:当Xamarin.Forms应用程序运行时,它可以使用.NET反射来访问自己的程序集和程序中的任何其他程序集。这意味着PCL中的代码可以使用反射来访问存在于引用PCL的平台程序集中的类。当然,这些类必须定义为公共类,但这只是唯一的要求。
在开始编写利用此技术的代码之前,您应该知道此解决方案已经以名为Dependency Service的Xamarin.Forms类的形式存在。此类使用.NET反射来搜索应用程序中的所有其他程序集(包括特定平台程序集本身),并提供对特定于平台的代码的访问。
DisplayPlatformInfo解决方案中说明了DependencyService的使用,该解决方案使用可移植类库作为共享代码。您可以通过在PCL项目中定义接口类型来开始使用DependencyService的过程,该接口类型声明要在平台项目中实现的方法的签名。这是IPlatformInfo:

点击(此处)折叠或打开

  1. namespace DisplayPlatformInfo
  2. {
  3.     public interface IPlatformInfo
  4.     {
  5.         string GetModel();


  6.         string GetVersion();
  7.     }
  8. }


你以前见过这两种方法。 它们与PlatInfoSap2中平台项目中的PlatformInfo类中实现的方法相同。
以与PlatInfoSap2非常相似的方式,DisplayPlatformInfo中的所有三个平台项目现在必须具有实现IPlatformInfo接口的类。 这是iOS项目中的类,名为PlatformInfo:

点击(此处)折叠或打开

  1. using System;
  2. using UIKit;
  3. using Xamarin.Forms;
  4. [assembly: Dependency( typeof(DisplayPlatformInfo.iOS.PlatformInfo) )]
  5. namespace DisplayPlatformInfo.iOS
  6. {
  7.     public class PlatformInfo : IPlatformInfo {
  8.         UIDevice device = new UIDevice();
  9.         public string GetModel()
  10.         {
  11.             return(device.Model.ToString() );
  12.         }


  13.         public string GetVersion()
  14.         {
  15.             return(String.Format( "{0} {1}", device.SystemName,
  16.                      device.SystemVersion ) );
  17.         }
  18.     }
  19. }

此类不是直接从PCL引用的,因此命名空间名称可以是您想要的任何名称。 在这里,它设置为与iOS项目中的其他代码相同的命名空间。 班级名称也可以是您想要的任何名称。 无论您如何命名,该类必须显式实现PCL中定义的IPlatformInfo接口:

点击(此处)折叠或打开

  1. public class PlatformInfo : IPlatformInfo

此外,必须在命名空间块之外的特殊属性中引用此类。 您将在using指令后面的文件顶部附近看到它:

点击(此处)折叠或打开

  1. [assembly: Dependency(typeof(DisplayPlatformInfo.iOS.PlatformInfo))]

定义此Dependency属性的DependencyAttribute类是Xamarin.Forms的一部分,专门用于与DependencyService连接。 参数是平台项目中类的Type对象,可供PCL访问。 在这种情况下,它就是这个PlatformInfo类。 此属性附加到平台程序集本身,因此在PCL中执行的代码不必搜索整个库以查找它。
这是PlatformInfo的Android版本:

点击(此处)折叠或打开

  1. using System;
  2. using Android.OS;
  3. using Xamarin.Forms;
  4. [assembly: Dependency( typeof(DisplayPlatformInfo.Droid.PlatformInfo) )]
  5. namespace DisplayPlatformInfo.Droid
  6. {
  7.     public class PlatformInfo : IPlatformInfo {
  8.         public string GetModel()
  9.         {
  10.             return(String.Format( "{0} {1}", Build.Manufacturer,
  11.                      Build.Model ) );
  12.         }


  13.         public string GetVersion()
  14.         {
  15.             return(Build.VERSION.Release.ToString() );
  16.         }
  17.     }
  18. }

这是UWP项目的一个:

点击(此处)折叠或打开

  1. using System;
  2. using Windows.Security.ExchangeActiveSyncProvisioning;
  3. using Xamarin.Forms;
  4. [assembly: Dependency( typeof(DisplayPlatformInfo.UWP.PlatformInfo) )]
  5. namespace DisplayPlatformInfo.UWP
  6. {
  7.     public class PlatformInfo : IPlatformInfo {
  8.         EasClientDeviceInformation devInfo = new EasClientDeviceInformation();
  9.         public string GetModel()
  10.         {
  11.             return(String.Format( "{0} {1}", devInfo.SystemManufacturer,
  12.                      devInfo.SystemProductName ) );
  13.         }


  14.         public string GetVersion()
  15.         {
  16.             return(devInfo.OperatingSystem);
  17.         }
  18.     }
  19. }

Windows 8.1和Windows Phone 8.1项目具有类似的文件,这些文件仅由命名空间不同。
然后,PCL中的代码可以使用DependencyService类访问特定平台的IPlatformInfo实现。 这是一个带有三个公共方法的静态类,其中最重要的是名为Get。 Get是一个泛型方法,其参数是您定义的接口,在本例中为IPlatformInfo。

点击(此处)折叠或打开

  1. IPlatformInfo platformInfo = DependencyService.Get<IPlatformInfo>();

Get方法返回实现IPlatformInfo接口的特定于平台的类的实例。 然后,您可以使用此对象进行特定于平台的调用。 这在DisplayPlatformInfo项目的代码隐藏文件中得到了证明:

点击(此处)折叠或打开

  1. namespace DisplayPlatformInfo
  2. {
  3.     public partial class DisplayPlatformInfoPage : ContentPage {
  4.         public DisplayPlatformInfoPage()
  5.         {
  6.             InitializeComponent();
  7.             IPlatformInfo platformInfo = DependencyService.Get<IPlatformInfo>();
  8.             modelLabel.Text        = platformInfo.GetModel();
  9.             versionLabel.Text    = platformInfo.GetVersion();
  10.         }
  11.     }
  12. }

Dependency Service缓存通过Get方法获取的对象的实例。 这加速了Get的后续使用,并且还允许接口的平台实现维护状态:平台实现中的任何字段和属性将在多个Get调用中保留。 这些类还可以包含事件或实现回调方法。
与PlatInfoSap2项目中显示的方法相比,依赖服务只需要更多的开销,并且由于各个平台类实现了在共享代码中定义的接口,因此更加结构化。
DependencyService不是在PCL中实现特定于平台的调用的唯一方法。 Adventurous开发人员可能希望使用依赖注入技术来配置PCL以调用平台项目。 但是DependencyService非常易于使用,它消除了在Xamarin.Forms应用程序中使用共享资产项目的大多数原因。

阅读(18205) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~