การสร้างแอปข้ามแพลตฟอร์มด้วย Xamarin: มุมมองของนักพัฒนา Android

เผยแพร่แล้ว: 2022-03-11

การเขียนโค้ดเพียงครั้งเดียวและใช้งานบนหลายแพลตฟอร์มเป็นความฝันของนักพัฒนาซอฟต์แวร์หลายคน แม้ว่าสิ่งนี้จะเป็นไปได้มาระยะหนึ่งแล้ว แต่ก็ต้องแลกมาด้วยค่าใช้จ่ายในการบำรุงรักษา ความง่ายในการทดสอบ หรือที่แย่กว่านั้นคือ ประสบการณ์ผู้ใช้ที่ไม่ดี

การพัฒนาแอปพลิเคชันมือถือโดยใช้ SDK ดั้งเดิมน่าจะเป็นจุดเริ่มต้นสำหรับนักพัฒนาทั้งหมดที่มีรากฐานมาจากขอบเขตของการพัฒนาแอปพลิเคชันเดสก์ท็อป ภาษาการเขียนโปรแกรมจะกลายเป็นอุปสรรคสำหรับบางคน: หากมีคนมีประสบการณ์ในการพัฒนา Java desktop หรือแอพพลิเคชั่นแบ็คเอนด์ การย้ายไปยังบริษัทพัฒนาแอพมือถือและการทำงานกับ Android จะรู้สึกง่ายกว่าการเริ่มต้นด้วย Objective-C ตั้งแต่เริ่มต้นสำหรับ iOS

ฉันเคยสงสัยเกี่ยวกับการพัฒนาแอปพลิเคชันข้ามแพลตฟอร์มอยู่เสมอ เฟรมเวิร์กที่ใช้ JavaScript เช่น Sencha, Cordova, Titanium ฯลฯ ไม่เคยพิสูจน์ว่าเป็นทางเลือกที่ชาญฉลาดเมื่อประสิทธิภาพเป็นสิ่งสำคัญ เฟรมเวิร์กเหล่านี้ขาด API และประสบการณ์ผู้ใช้ที่แปลกใหม่

แต่แล้ว ฉันเจอซามาริน

การพัฒนาข้ามแพลตฟอร์มด้วย Xamarin

ในบทความนี้ คุณจะได้เรียนรู้วิธีที่คุณสามารถใช้ Xamarin เพื่อแชร์รหัสข้ามแพลตฟอร์มต่างๆ ได้โดยไม่กระทบต่อการพัฒนาแอปพลิเคชันบนมือถือในด้านอื่นๆ บทความนี้จะเน้นไปที่ Android และ iOS โดยเฉพาะ แต่คุณสามารถใช้แนวทางที่คล้ายกันเพื่อเพิ่มการรองรับสำหรับแพลตฟอร์มอื่นๆ ที่ Xamarin รองรับ

Xamarin คืออะไร?

Xamarin เป็นแพลตฟอร์มการพัฒนาที่ให้คุณเขียนแอพพลิเคชั่นข้ามแพลตฟอร์ม—แต่เนทีฟ—สำหรับ iOS, Android และ Windows Phone ใน C# และ .NET

Xamarin ให้การเชื่อมโยง C # กับ Android และ iOS API ดั้งเดิม ฟีเจอร์นี้ช่วยให้คุณใช้อินเทอร์เฟซผู้ใช้ การแจ้งเตือน กราฟิก แอนิเมชั่น และฟีเจอร์โทรศัพท์อื่นๆ ของ Android และ iOS ทั้งหมดได้โดยใช้ C#

Xamarin รุ่นใหม่ของ Android และ iOS แต่ละรุ่นจะจับคู่กับรุ่นใหม่ที่มีการเชื่อมโยงสำหรับ API ใหม่

พอร์ต .NET ของ Xamarin มีคุณสมบัติต่างๆ เช่น ชนิดข้อมูล ข้อมูลทั่วไป การรวบรวมขยะ การสืบค้นแบบรวมภาษา (LINQ) รูปแบบการเขียนโปรแกรมแบบอะซิงโครนัส ผู้รับมอบสิทธิ์ และชุดย่อยของ Windows Communication Foundation (WCF) ไลบรารีได้รับการจัดการโดยใช้เวลาเพียงไม่นานเพื่อรวมเฉพาะส่วนประกอบที่อ้างอิงเท่านั้น

Xamarin.Forms เป็นเลเยอร์ที่ด้านบนของการเชื่อมโยง UI อื่น ๆ และ Windows Phone API ซึ่งมีไลบรารีส่วนต่อประสานผู้ใช้ข้ามแพลตฟอร์มอย่างสมบูรณ์

ขอบเขตของ Xamarin

การเขียนแอพพลิเคชั่นข้ามแพลตฟอร์ม

ในการเขียนแอปพลิเคชันข้ามแพลตฟอร์มด้วย Xamarin นักพัฒนาจำเป็นต้องเลือกหนึ่งในสองประเภทของโครงการที่มีอยู่:

  • ห้องสมุดแบบพกพา (PCL)
  • โครงการร่วม

PCL อนุญาตให้คุณเขียนโค้ดที่สามารถแชร์ระหว่างหลายแพลตฟอร์มได้ แต่มีข้อจำกัดเพียงข้อเดียว เนื่องจาก .NET API ทั้งหมดนั้นไม่มีให้ใช้งานในทุกแพลตฟอร์ม ด้วยโปรเจ็กต์ PCL คุณจะต้องจำกัดให้ทำงานบนแพลตฟอร์มที่เป็นเป้าหมาย

การเชื่อมต่อและข้อจำกัดของ Xamarin

ตารางด้านล่างแสดงให้เห็นว่า API ใดบ้างที่พร้อมใช้งานบนแพลตฟอร์มใด:

คุณสมบัติ .NET Framework แอพ Windows Store ซิลเวอร์ไลท์ Windows Phone ซามาริน
แกน Y Y Y Y Y
LINQ Y Y Y Y Y
สืบค้นไม่ได้ Y Y Y 7.5+ Y
การทำให้เป็นอนุกรม Y Y Y Y Y
คำอธิบายประกอบข้อมูล 4.0.3+ Y Y Y Y

ในระหว่างกระบวนการสร้าง PCL จะถูกคอมไพล์เป็น DLL ที่แยกจากกัน และโหลดโดย Mono ระหว่างรันไทม์ การใช้งานอินเทอร์เฟซเดียวกันที่แตกต่างกันสามารถจัดเตรียมได้ระหว่างรันไทม์

ในทางกลับกัน โครงการที่ใช้ร่วมกันช่วยให้คุณควบคุมได้มากขึ้นโดยอนุญาตให้คุณเขียนโค้ดเฉพาะแพลตฟอร์มสำหรับแต่ละแพลตฟอร์มที่คุณต้องการสนับสนุน รหัสในโครงการที่ใช้ร่วมกันสามารถมีคำสั่งคอมไพเลอร์ที่จะเปิดใช้งานหรือปิดใช้งานส่วนของรหัสขึ้นอยู่กับโครงการแอปพลิเคชันที่ใช้รหัส

ไม่เหมือนกับ PCL โปรเจ็กต์ที่ใช้ร่วมกันจะไม่สร้าง DLL ใดๆ รหัสรวมอยู่ในโครงการสุดท้ายโดยตรง

ให้โครงสร้างรหัสข้ามแพลตฟอร์มของคุณด้วย MvvmCross

รหัสที่ใช้ซ้ำได้อาจช่วยประหยัดเงินและเวลาสำหรับทีมพัฒนา อย่างไรก็ตาม โค้ดที่มีโครงสร้างที่ดีทำให้ชีวิตนักพัฒนาง่ายขึ้นมาก ไม่มีใครชื่นชมโค้ดที่ปราศจากข้อผิดพลาดที่เขียนขึ้นอย่างสวยงามมากไปกว่านักพัฒนา

Xamarin เองมีกลไกที่ทำให้การเขียนโค้ดข้ามแพลตฟอร์มที่ใช้ซ้ำได้ง่ายกว่ามาก

นักพัฒนามือถือคุ้นเคยกับสถานการณ์ที่พวกเขาต้องเขียนตรรกะเดียวกันสองครั้งขึ้นไปเพื่อรองรับ iOS, Android และแพลตฟอร์มอื่นๆ แต่ด้วย Xamarin ดังที่อธิบายไว้ในบทที่แล้ว มันง่ายที่จะนำโค้ดกลับมาใช้ใหม่ ซึ่งเขียนขึ้นสำหรับแพลตฟอร์มหนึ่งสำหรับแพลตฟอร์มอื่นด้วยเช่นกัน

MvvmCross เกิดขึ้นที่ไหน?

MvvmCross เนื่องจากชื่ออาจมีการบอกใบ้ ทำให้สามารถใช้รูปแบบ MVVM ในแอปพลิเคชัน Xamarin ได้ มันมาพร้อมกับไลบรารี API และยูทิลิตี้มากมายซึ่งมีประโยชน์อย่างมากในการพัฒนาแอปพลิเคชันข้ามแพลตฟอร์ม

MvvmCross สามารถลดจำนวนโค้ดสำเร็จรูปที่คุณจะเขียนได้อย่างมาก (บางครั้งหลายครั้งในภาษาต่างๆ) ในแนวทางอื่นๆ ในการพัฒนาแอปพลิเคชัน

โครงสร้างของโซลูชัน MvvmCross

ชุมชน MvvmCross แนะนำวิธีที่ง่ายและมีประสิทธิภาพในการจัดโครงสร้างโซลูชัน MvvmCross:

 <ProjectName>.Core <ProjectName>.UI.Droid <ProjectName>.UI.iOS

โปรเจ็กต์หลักในโซลูชัน MvvmCross เกี่ยวข้องกับโค้ดที่ใช้ซ้ำได้ โครงการ Core เป็นโครงการ Xamarin PCL โดยเน้นที่การนำกลับมาใช้ใหม่ได้

โค้ดใดๆ ที่เขียนใน Core ควรเป็นแพลตฟอร์มที่ไม่เชื่อเรื่องพระเจ้าในวิธีสูงสุด ควรมีตรรกะที่สามารถนำมาใช้ซ้ำได้ในทุกแพลตฟอร์ม โปรเจ็กต์หลักต้องไม่ใช้ Android หรือ iOS API หรือเข้าถึงสิ่งที่เฉพาะเจาะจงสำหรับแพลตฟอร์มใดๆ

เลเยอร์ตรรกะทางธุรกิจ ชั้นข้อมูล และการสื่อสารแบ็คเอนด์ล้วนเป็นตัวเลือกที่สมบูรณ์แบบสำหรับการรวมไว้ในโครงการหลัก การนำทางผ่านลำดับชั้นการดู (กิจกรรม ส่วนย่อย ฯลฯ) จะทำสำเร็จใน Core

ก่อนดำเนินการต่อ จำเป็นต้องเข้าใจรูปแบบการออกแบบสถาปัตยกรรมหนึ่งรูปแบบซึ่งเป็นสิ่งสำคัญสำหรับการทำความเข้าใจ MvvmCross และวิธีการทำงาน ดังที่เห็นได้จากชื่อ MvvmCross ขึ้นอยู่กับรูปแบบ MVVM เป็นอย่างมาก

MVVM เป็นรูปแบบการออกแบบสถาปัตยกรรมที่อำนวยความสะดวกในการแยกส่วนต่อประสานกราฟิกกับผู้ใช้ออกจากตรรกะทางธุรกิจและข้อมูลแบ็คเอนด์

รูปแบบนี้ใช้ใน MvvmCross อย่างไร

เนื่องจากเราต้องการให้โค้ดของเราสามารถนำกลับมาใช้ใหม่ได้ในระดับสูง เราจึงต้องการมีใน Core ของเรามากที่สุด ซึ่งเป็นโปรเจ็กต์ PCL เนื่องจากจำนวนการดูเป็นเพียงส่วนเดียวของโค้ดที่แตกต่างจากแพลตฟอร์มหนึ่งไปอีกแพลตฟอร์มหนึ่ง เราจึงไม่สามารถใช้ซ้ำได้ในทุกแพลตฟอร์ม ส่วนนั้นถูกนำไปใช้ในโครงการที่เกี่ยวข้องกับแพลตฟอร์ม

Mvvmโครงสร้างข้าม

MvvmCross ช่วยให้เราสามารถประสานการนำทางแอปพลิเคชันจาก Core โดยใช้ ViewModels

ด้วยข้อมูลพื้นฐานและรายละเอียดทางเทคนิค เรามาเริ่มต้นกับ Xamarin โดยสร้างโปรเจ็กต์ MvvmCross Core ของเราเอง:

การสร้าง MvvmCross Core Project

เปิด Xamarin Studio และสร้างโซลูชันชื่อ ToptalExampleSolution :

การสร้างโซลูชัน

เนื่องจากเรากำลังสร้างโครงการหลัก จึงเป็นความคิดที่ดีที่จะยึดติดกับหลักการตั้งชื่อ ตรวจสอบให้แน่ใจว่าได้เพิ่มส่วนต่อท้าย Core เข้ากับชื่อโปรเจ็กต์แล้ว

ในการรับการสนับสนุน MvvmCross จำเป็นต้องเพิ่มไลบรารี MvvmCross ในโครงการของเรา ยิ่งไปกว่านั้น เราสามารถใช้การรองรับในตัวสำหรับ NuGet ใน Xamarin Studio

หากต้องการเพิ่มไลบรารีให้คลิกขวาที่โฟลเดอร์ Packages แล้วเลือกตัวเลือก Add Packages…

ในช่องค้นหา เราสามารถค้นหา MvvmCross ซึ่งจะกรองผลลัพธ์ที่เกี่ยวข้องกับ MvvmCross ดังที่แสดงด้านล่าง:

กรองผลลัพธ์

การคลิกที่ปุ่ม เพิ่มแพ็คเกจ จะเป็นการเพิ่มไปยังโครงการ

ด้วยการเพิ่ม MvvmCross ในโครงการของเรา เราก็พร้อมที่จะเขียนโค้ดหลักของเราแล้ว

มากำหนด ViewModel แรกของเรากัน ในการสร้างโฟลเดอร์ ให้สร้างลำดับชั้นของโฟลเดอร์ดังนี้:

ลำดับชั้นของโฟลเดอร์ที่แนะนำ

นี่คือสิ่งที่แต่ละโฟลเดอร์เกี่ยวกับ:

  • โมเดล: โมเดลโดเมนที่แสดงเนื้อหาในสถานะจริง
  • บริการ: โฟลเดอร์ที่ให้บริการของเรา (ตรรกะทางธุรกิจ ฐานข้อมูล ฯลฯ)
  • ViewModel: วิธีที่เราสื่อสารกับโมเดลของเรา

ViewModel แรกของเราเรียกว่า FirstViewModel.cs

 public class FirstViewModel : MvxViewModel { private string _firstName; private string _lastName; private string _fullName; public string FirstName { get { return _firstName; } set { _lastName = value; RaisePropertyChanged(); } } public string LastName { get { return _lastName; } set { _lastName = value; RaisePropertyChanged(); } } public string FullName { get { return _fullName; } set { _fullName = value; RaisePropertyChanged(); } } public IMvxCommand ConcatNameCommand { get { return new MvxCommand(() => { FullName = $"{FirstName} {LastName}"; }); } public IMvxCommand NavigateToSecondViewModelCommand { get { return new MvxCommand(() => { ShowViewModel<SecondViewModel>(); }); } } }

ตอนนี้เรามี ViewModel แรกแล้ว เราก็สามารถสร้างมุมมองแรกและเชื่อมโยงสิ่งต่างๆ เข้าด้วยกันได้

Android UI

ในการแสดงเนื้อหาของ ViewModel เราจำเป็นต้องสร้าง UI

ขั้นตอนแรกในการสร้าง Android UI คือการสร้างโครงการ Android ในโซลูชันปัจจุบัน ในการทำเช่นนั้น ให้คลิกขวาที่ชื่อโซลูชันแล้วเลือก เพิ่ม -> เพิ่มโครงการใหม่… ในวิซาร์ด ให้เลือกแอป Android และตรวจสอบให้แน่ใจว่าคุณตั้งชื่อโปรเจ็ ToptalExample.UI.Droid ของคุณ

ตามที่อธิบายไว้ก่อนหน้านี้ ตอนนี้เราต้องเพิ่มการพึ่งพา MvvmCross สำหรับ Android โดยทำตามขั้นตอนเดียวกับสำหรับโครงการหลักเพื่อเพิ่มการพึ่งพา NuGet

หลังจากเพิ่มการพึ่งพา MvvmCross จำเป็นต้องเพิ่มการอ้างอิงไปยังโครงการหลักของเรา เพื่อให้เราสามารถใช้โค้ดของเราที่เขียนที่นั่น ในการเพิ่มการอ้างอิงไปยังโครงการ PCL ให้คลิกขวาที่โฟลเดอร์ References และเลือกตัวเลือก Edit References... บนแท็บโปรเจ็กต์ เลือกโปรเจ็กต์หลักที่สร้างไว้ก่อนหน้านี้แล้วคลิกตกลง

เพิ่มการอ้างอิงไปยังโครงการ PCL

ส่วนต่อไปอาจเข้าใจยากเล็กน้อย

ตอนนี้เราต้องบอก MvvmCross ว่าควรตั้งค่าแอปพลิเคชันของเราอย่างไร ในการทำเช่นนั้น เราต้องสร้างคลาสการ Setup :

 namespace ToptalExample.UI.Droid { public class Setup : MvxAndroidSetup { public Setup(Context context) : base(context) { } protected override IMvxApplication CreateApp() { return new Core.App(); } } }

ดังที่เห็นได้จากคลาส เรากำลังบอก MvvmCross ให้ CreateApp ตามการใช้งาน Core.App ซึ่งเป็นคลาสที่กำหนดไว้ใน Core และแสดงด้านล่าง:

 public class App : MvxApplication { public override void Initialize() { RegisterAppStart(new AppStart()); } } public class AppStart : MvxNavigatingObject, IMvxAppStart { public void Start(object hint = null) { ShowViewModel<FirstViewModel>(); } }

ในคลาส App เรากำลังสร้างอินสแตนซ์ของ AppStart ซึ่งจะแสดง ViewModel แรกของเรา

สิ่งเดียวที่เหลือในตอนนี้คือการสร้างไฟล์ Android Layout ซึ่งจะถูกผูกไว้โดย MvvmCross:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro xmlns:local="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="match_parent" android:layout_height="match_parent" local:MvxBind="Text FirstName" /> <EditText android:layout_width="match_parent" android:layout_height="match_parent" local:MvxBind="Text LastName" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" local:MvxBind="Text FullName" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" local:MvxBind="Click ConcatNameCommand" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" local:MvxBind="Click NavigateToSecondViewModelCommand" /> </LinearLayout>

ในไฟล์เลย์เอาต์ เรามีการโยงซึ่ง MvvmCross แก้ไขโดยอัตโนมัติ สำหรับ EditText เรากำลังสร้างการเชื่อมโยงสำหรับคุณสมบัติ Text ซึ่งจะเป็นการโยงแบบสองทาง การเปลี่ยนแปลงใดๆ ที่เรียกใช้จากฝั่ง ViewModel จะถูกสะท้อนโดยอัตโนมัติในมุมมองและในทางกลับกัน

คลาส View อาจเป็นกิจกรรมหรือส่วนย่อยก็ได้ เพื่อความง่าย เรากำลังใช้กิจกรรมที่โหลดเค้าโครงที่กำหนด:

 [Activity(Label = "ToptalExample.UI.Droid", Theme = "@style/Theme.AppCompat", MainLauncher = true, Icon = "@mipmap/icon")] public class MainActivity : MvxAppCompatActivity<FirstViewModel> { protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); SetContentView(Resource.Layout.Main); } }

สำหรับปุ่มแรก เรามีการผูกคำสั่งซึ่งหมายความว่าเมื่อเราคลิกที่ปุ่ม MvvmCross จะเรียก ContactNameCommand จาก ViewModel

สำหรับปุ่มที่สอง เราจะแสดง ViewModel อื่น

iOS UI

การสร้างโปรเจ็กต์ iOS ไม่ได้แตกต่างจากการสร้างโปรเจ็กต์ Android เลย คุณต้องทำตามขั้นตอนที่คล้ายกันในการเพิ่มโปรเจ็กต์ใหม่ คราวนี้แทนที่จะสร้าง Android ให้สร้างโปรเจ็กต์ iOS เพียงให้แน่ใจว่าคุณรักษาหลักการตั้งชื่อให้สอดคล้องกัน

หลังจากเพิ่มโปรเจ็กต์ iOS แล้ว คุณต้องเพิ่มการพึ่งพาสำหรับ MvvmCross iOS ขั้นตอนจะเหมือนกับ Core และ Android อย่างแน่นอน (คลิกขวาที่ References ในโครงการ iOS ของคุณแล้วคลิก Add References… )

ตอนนี้ อย่างที่เราทำกับ Android จำเป็นต้องสร้างคลาสการ Setup ซึ่งจะบอกให้ MvvmCross วิธีตั้งค่าแอปพลิเคชันของเรา

 public class Setup : MvxIosSetup { public Setup(MvxApplicationDelegate appDelegate, IMvxIosViewPresenter presenter) : base(appDelegate, presenter) { } protected override MvvmCross.Core.ViewModels.IMvxApplication CreateApp() { return new App(); } }

โปรดทราบว่าคลาส Setup จะขยาย MvxIosSetup และสำหรับ Android ได้ขยาย MvxAndroidSetup

อีกอย่างหนึ่งที่นี่คือ เราต้องเปลี่ยนคลาส AppDelegate ของเรา

AppDelegate บน iOS มีหน้าที่ในการเปิดตัวอินเทอร์เฟซผู้ใช้ ดังนั้นเราต้องบอกว่ามุมมองจะนำเสนอบน iOS อย่างไร คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับผู้นำเสนอได้ที่นี่

 [Register("AppDelegate")] public class AppDelegate : MvxApplicationDelegate { // class-level declarations public override UIWindow Window { get; set; } public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) { Window = new UIWindow(UIScreen.MainScreen.Bounds); var presenter = new MvxIosViewPresenter(this, Window); var setup = new Setup(this, presenter); setup.Initialize(); var startup = Mvx.Resolve<IMvxAppStart>(); startup.Start(); Window.MakeKeyAndVisible(); return true; } }

ในการนำเสนอ ViewModel ของเรา เราจำเป็นต้องสร้างมุมมอง สำหรับกรณีนั้น ให้สร้าง ViewController โดยคลิกขวาที่โปรเจ็กต์แล้วเลือก Add -> New File แล้วเลือก ViewController จากส่วน iOS ซึ่งเราจะตั้งชื่อว่า FirstViewController

Xamarin สร้างไฟล์สามไฟล์ที่เราจะกำหนดว่าการผูกของเราจะเป็นอย่างไร ต่างจาก Android สำหรับ iOS เราต้องกำหนดการเชื่อมโยงของเราในวิธีที่ต่างออกไป ผ่านโค้ด (แม้ว่าเราจะสามารถทำได้บน Android เช่นกัน และในบางกรณีก็จำเป็นต้องทำเช่นนั้น)

เมื่อจำเป็นต้องนำทางระหว่างมุมมอง จะทำผ่าน ViewModel ในคำสั่ง NavigateToSecondViewModelCommand เมธอด ShowViewModel<SecondViewModel>() จะค้นหามุมมองที่เหมาะสมและนำทางไปยังมุมมองนั้น

แต่ MVVMCross รู้ได้อย่างไรว่าต้องโหลดมุมมองใด

ไม่มีเวทย์มนตร์ในนั้น เมื่อเราสร้างมุมมองสำหรับ Android (Activity หรือ Fragment) เรากำลังขยายหนึ่งในคลาสฐานที่มีพารามิเตอร์ประเภท ( MvxAppCompatActivity<VM> ) เมื่อเราเรียก ShowViewMolel<VM> , MvvmCross จะ View ซึ่งขยายคลาส Activity หรือ Fragment ด้วยพารามิเตอร์ประเภท VM นี่คือสาเหตุที่คุณไม่ได้รับอนุญาตให้มีคลาสมุมมองสองคลาสสำหรับ ViewModel เดียวกัน

การผกผันของการควบคุม

เนื่องจาก Xamarin เป็นเพียงการจัดเตรียม C# wrapper ให้กับ Native APIs จึงไม่ได้จัดเตรียมกลไกการพึ่งพา (DI) หรือการผกผันของการควบคุม (IoC) ในรูปแบบใดๆ

หากไม่มีการฉีดรันไทม์ของการพึ่งพาหรือการฉีดเวลาคอมไพล์ มันไม่ง่ายที่จะสร้างส่วนประกอบที่เชื่อมต่อแบบหลวม ใช้ซ้ำได้ ทดสอบได้ และบำรุงรักษาได้ง่าย แนวคิดของ IoC และ DI เป็นที่ทราบกันมานานแล้ว รายละเอียดเกี่ยวกับ IoC สามารถพบได้ในบทความออนไลน์มากมาย คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับรูปแบบเหล่านี้ได้จากบทความแนะนำของ Martin Fowler

IoC พร้อมใช้งานตั้งแต่เวอร์ชันก่อนหน้าของ MvvmCrosses และอนุญาตให้ฉีดการพึ่งพาที่รันไทม์เมื่อแอปพลิเคชันเริ่มทำงานและเมื่อใดก็ตามที่จำเป็น

เพื่อให้ได้ส่วนประกอบที่เป็นคู่กันอย่างอิสระ เราไม่ควรต้องมีการใช้งานคลาสที่เป็นรูปธรรม การกำหนดให้ใช้งานจริงจะจำกัดความสามารถในการเปลี่ยนลักษณะการทำงานของการใช้งานระหว่างรันไทม์ (คุณไม่สามารถแทนที่ด้วยการใช้งานอื่นได้) ทำให้ยากต่อการทดสอบส่วนประกอบเหล่านี้

ด้วยเหตุผลดังกล่าว เราจะประกาศอินเทอร์เฟซสำหรับการดำเนินการที่เป็นรูปธรรม

 public interface IPasswordGeneratorService { string Generate(int length); }

และการนำไปปฏิบัติ:

 public class PasswordGeneratorService : IPasswordGeneratorService { public string Generate(int length) { var val; var res = new StringBuilder(); var rnd = new Random(); while (0 < length--) { res.Append(valid[rnd.Next(valid.Length)]); } return res.ToString(); } }

ViewModel ของเราสามารถกำหนดให้มีอินสแตนซ์ของอินเทอร์เฟซ IPasswordGenerationService ซึ่งเรามีหน้าที่รับผิดชอบในการจัดหา

เพื่อให้ MvvmCross ฉีดการใช้งาน PasswordGeneratorService ที่รันไทม์ เราจำเป็นต้องบอก MvvmCross ว่าจะใช้การใช้งานแบบใด หากเราต้องการใช้หนึ่งการใช้งานสำหรับทั้งสองแพลตฟอร์ม เราสามารถลงทะเบียนการใช้งานใน App.cs หลังจากการลงทะเบียนแอปพลิเคชัน:

 public override void Initialize() { RegisterAppStart(new AppStart()); Mvx.LazyConstructAndRegisterSingleton<IPasswordGeneratorService, PasswordGeneratorService>(); }

การเรียกใช้เมธอดแบบคงที่ข้างต้น LazyConstructAndRegisterSingleton<TInterface, TType> ลงทะเบียนการใช้งานที่จะฉีด เมธอดนี้ลงทะเบียนการใช้งานที่เหมาะสม แต่ไม่ได้สร้างวัตถุ

อ็อบเจ็กต์จะถูกสร้างขึ้นเมื่อจำเป็นเท่านั้นและมีเพียงครั้งเดียวเท่านั้นเนื่องจากได้รับการลงทะเบียนเป็นซิงเกิลตัน

หากเราต้องการสร้างวัตถุซิงเกิลตันทันที สามารถทำได้โดยเรียก Mvx.RegisterSingleton<TInterface>()

มีบางกรณีที่เราไม่ต้องการให้มีเพียงซิงเกิลตันในใบสมัครของเรา วัตถุของเราอาจไม่ปลอดภัยสำหรับเธรดหรืออาจมีเหตุผลอื่นที่เราต้องการให้มีอินสแตนซ์ใหม่อยู่เสมอ หากเป็นกรณีนี้ MvvmCross จะจัดเตรียมวิธีการ Mvx.RegisterType<TInterface,TType>() ซึ่งสามารถใช้เพื่อลงทะเบียนการใช้งานในลักษณะที่สร้างอินสแตนซ์ใหม่ทุกครั้งที่จำเป็น

ในกรณีที่คุณจำเป็นต้องจัดเตรียมการใช้งานที่เป็นรูปธรรมแยกต่างหากสำหรับแต่ละแพลตฟอร์ม คุณสามารถทำได้ในโปรเจ็กต์เฉพาะแพลตฟอร์ม:

 public class DroidPasswodGeneratorService : IPasswordGeneratorService { public string Generate(int length) { return "DroidPasswordGenerator"; } }

และการลงทะเบียนการใช้งานของเราเสร็จสิ้นในคลาส Setup.cs ภายใต้โครงการ Droid:

 protected override void InitializePlatformServices() { base.InitializePlatformServices(); Mvx.LazyConstructAndRegisterSingleton<IPasswordGeneratorService, DroidPasswodGeneratorService>(); }

หลังจากเริ่มต้นรหัส PCL แล้ว MvvmCross จะเรียก InitializePlatformServices และลงทะเบียนการใช้งานบริการเฉพาะแพลตฟอร์มของเรา

เมื่อเราลงทะเบียนการใช้งานซิงเกิลตันหลายรายการ MvvmCross จะใช้เฉพาะการใช้งานที่ลงทะเบียนล่าสุดเท่านั้น การลงทะเบียนอื่นๆ ทั้งหมดจะถูกยกเลิก

สร้างแอปข้ามแพลตฟอร์มด้วย Xamarin

ในบทความนี้ คุณได้เห็นแล้วว่า Xamarin อนุญาตให้คุณแชร์โค้ดบนแพลตฟอร์มต่างๆ ได้อย่างไร โดยยังคงรักษาความรู้สึกดั้งเดิมและประสิทธิภาพของแอปพลิเคชันไว้

MvvmCross มอบความเป็นนามธรรมอีกชั้นหนึ่ง ซึ่งช่วยเสริมประสบการณ์ในการสร้างแอปพลิเคชันข้ามแพลตฟอร์มด้วย Xamarin รูปแบบ MVVM มีวิธีสร้างการนำทางและโฟลว์การโต้ตอบของผู้ใช้ที่เหมือนกันสำหรับทุกแพลตฟอร์ม ทำให้จำนวนโค้ดเฉพาะแพลตฟอร์มที่คุณต้องเขียนจำกัดเฉพาะการดูเท่านั้น

ฉันหวังว่าบทความนี้จะให้เหตุผลกับคุณในการดู Xamarin และกระตุ้นให้คุณสร้างแอปพลิเคชันข้ามแพลตฟอร์มตัวต่อไปด้วย