การสร้างแอปข้ามแพลตฟอร์มด้วย Xamarin: มุมมองของนักพัฒนา Android
เผยแพร่แล้ว: 2022-03-11การเขียนโค้ดเพียงครั้งเดียวและใช้งานบนหลายแพลตฟอร์มเป็นความฝันของนักพัฒนาซอฟต์แวร์หลายคน แม้ว่าสิ่งนี้จะเป็นไปได้มาระยะหนึ่งแล้ว แต่ก็ต้องแลกมาด้วยค่าใช้จ่ายในการบำรุงรักษา ความง่ายในการทดสอบ หรือที่แย่กว่านั้นคือ ประสบการณ์ผู้ใช้ที่ไม่ดี
การพัฒนาแอปพลิเคชันมือถือโดยใช้ SDK ดั้งเดิมน่าจะเป็นจุดเริ่มต้นสำหรับนักพัฒนาทั้งหมดที่มีรากฐานมาจากขอบเขตของการพัฒนาแอปพลิเคชันเดสก์ท็อป ภาษาการเขียนโปรแกรมจะกลายเป็นอุปสรรคสำหรับบางคน: หากมีคนมีประสบการณ์ในการพัฒนา Java desktop หรือแอพพลิเคชั่นแบ็คเอนด์ การย้ายไปยังบริษัทพัฒนาแอพมือถือและการทำงานกับ Android จะรู้สึกง่ายกว่าการเริ่มต้นด้วย Objective-C ตั้งแต่เริ่มต้นสำหรับ iOS
ฉันเคยสงสัยเกี่ยวกับการพัฒนาแอปพลิเคชันข้ามแพลตฟอร์มอยู่เสมอ เฟรมเวิร์กที่ใช้ JavaScript เช่น Sencha, Cordova, Titanium ฯลฯ ไม่เคยพิสูจน์ว่าเป็นทางเลือกที่ชาญฉลาดเมื่อประสิทธิภาพเป็นสิ่งสำคัญ เฟรมเวิร์กเหล่านี้ขาด API และประสบการณ์ผู้ใช้ที่แปลกใหม่
แต่แล้ว ฉันเจอซามาริน
ในบทความนี้ คุณจะได้เรียนรู้วิธีที่คุณสามารถใช้ 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 นักพัฒนาจำเป็นต้องเลือกหนึ่งในสองประเภทของโครงการที่มีอยู่:
- ห้องสมุดแบบพกพา (PCL)
- โครงการร่วม
PCL อนุญาตให้คุณเขียนโค้ดที่สามารถแชร์ระหว่างหลายแพลตฟอร์มได้ แต่มีข้อจำกัดเพียงข้อเดียว เนื่องจาก .NET API ทั้งหมดนั้นไม่มีให้ใช้งานในทุกแพลตฟอร์ม ด้วยโปรเจ็กต์ PCL คุณจะต้องจำกัดให้ทำงานบนแพลตฟอร์มที่เป็นเป้าหมาย
ตารางด้านล่างแสดงให้เห็นว่า 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 เนื่องจากจำนวนการดูเป็นเพียงส่วนเดียวของโค้ดที่แตกต่างจากแพลตฟอร์มหนึ่งไปอีกแพลตฟอร์มหนึ่ง เราจึงไม่สามารถใช้ซ้ำได้ในทุกแพลตฟอร์ม ส่วนนั้นถูกนำไปใช้ในโครงการที่เกี่ยวข้องกับแพลตฟอร์ม
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... บนแท็บโปรเจ็กต์ เลือกโปรเจ็กต์หลักที่สร้างไว้ก่อนหน้านี้แล้วคลิกตกลง
ส่วนต่อไปอาจเข้าใจยากเล็กน้อย
ตอนนี้เราต้องบอก 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 และกระตุ้นให้คุณสร้างแอปพลิเคชันข้ามแพลตฟอร์มตัวต่อไปด้วย