Sử dụng DependencyService trong Xamarin Form



  • 1. Giới thiệu

    Như đã biết tầng share-code là nơi chứa các code không phụ thuộc vào nền tảng, đó là code chung giữa các platform: iOS, Android, Windows Phone. Chính vì thế rất khó để viết các đoạn code đặc thù của từng nền tảng. Thay vào đó, chúng ta viết các đoạn code đặc thù cho riêng từng platform, nhưng lại có thể "invoke" nó trên tầng share-code bằng DependencyService. Bản chất của c là interface và gọi các phần code đặc thù theo nền tảng đã implement interface đó.

    Vậy DependencyService hoạt động thế nào?
    Xamarin Form cần 3 thành phần sau để DependencyService có thể hoạt động:

    • Interface: Những function yêu cầu được định nghĩa ở đây, trong phần share-code
    • Implementation Per Platform: Phần code implement cho interface đó, và được viết cho từng nền tảng: iOS, Android, Windows Phone. Tuy nhiên các class implement interface đó, cần phải được đăng kí, để Dependency Service có thể biết được, và điều hướng ("invoke") đến các hàm đó trong run time.
    • Call to DependencyService: Dependency Service chỉ có thể được gọi ở tầng share-code. Mỗi plaftorm cần phải implement tất cả các hàm của interface đó nếu muốn function hoạt động đúng trên nền tảng mình mong muốn.

    Cấu trúc của Dependency Service như hình bên dưới:

    2. Interface

    Interface là nơi chúng ta thiết kế, định nghĩa cách chúng ta tương tác với các platform. Ví dụ bên dưới là một định nghĩa interface, cho phép phát âm một text được truyền vào, tuy nhiên phần implement được "vứt" xuống cho từng platform thực hiện.

    public interface ITextToSpeech {
        void Speak ( string text );
    }
    

    3.Implementation per Platform

    Sau khi đã có interface, chúng ta cầm implement các function cho interface đó hướng đến từng nền tảng mà chúng ta nhắm đến. Ví dụ dưới là một class thực thi interface cho nền tảng Windows Phone:

    namespace TextToSpeech.WinPhone
    {
      public class TextToSpeechImplementation : ITextToSpeech
      {
          public TextToSpeechImplementation() {}
    
          public async void Speak(string text)
          {
              SpeechSynthesizer synth = new SpeechSynthesizer();
              await synth.SpeakTextAsync(text);
          }
      }
    }
    

    Lứu ý mỗi class thực thi interface cần phải có một constructor mặc định, đảm bảo sao cho Dependency Service có thể tự tạo đối tượng cho class đó.

    3. Registration

    Mỗi một class mà thực thi interface đó, cần phải được đăng kí với Dependency Service, ví dụ bên dưới là đoạn code đăng kí class TextToSpeechImplementation, phía trên phần khai báo class.

    using TextToSpeech.WinPhone;
    
    [assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
    namespace TextToSpeech.WinPhone {
      ...
    

    4. Call to DependencyService

    Sau khi tất cả các nền tảng đã được thực thi interface trên, chúng ta có thể invoke các phần thực thi đó, cho từng nền tảng tại run time.

    DependencyService.Get<ITextToSpeech>().Speak("Hello from Xamarin Forms");
    

    Đơn giản có thể thấy, đoạn code DependencyService.Get<T> tìm đến phần code thực thì interface T ứng với nền tảng đang chạy.

    5. Solution Structure

    Chúng ta có thể thấy răng, sulution được chia thành 3 project riêng biệt:

    • UsingDependencyService: đây là project chứa phần share-code giữa tất cả nền tảng.
    using System;
    using Xamarin.Forms;
    
    namespace c
    {
    	public class MainPage : ContentPage
    	{
    		public MainPage ()
    		{
    			var speak = new Button {
    				Text = "Hello, Forms !",
    				VerticalOptions = LayoutOptions.CenterAndExpand,
    				HorizontalOptions = LayoutOptions.CenterAndExpand,
    			};
    			speak.Clicked += (sender, e) => {
    				DependencyService.Get<ITextToSpeech>().Speak("Hello from Xamarin Forms");
    			};
    			Content = speak;
    		}
    	}
    }
    

    Ở MainPage.cs chúng ta invoke phần code thực thi interface ITextToSpeech của từng nền tảng.

    • UsingDependencyService.iOS
    using System;
    using AVFoundation;
    using Xamarin.Forms;
    using UsingDependencyService.iOS;
    
    [assembly: Dependency (typeof (TextToSpeech_iOS))]
    
    namespace UsingDependencyService.iOS
    {
    	public class TextToSpeech_iOS : ITextToSpeech
    	{
    		public TextToSpeech_iOS ()
    		{
    		}
    
    		public void Speak (string text)
    		{
    			var speechSynthesizer = new AVSpeechSynthesizer ();
    
    			var speechUtterance = new AVSpeechUtterance (text) {
    				Rate = AVSpeechUtterance.MaximumSpeechRate/4,
    				Voice = AVSpeechSynthesisVoice.FromLanguage ("en-US"),
    				Volume = 0.5f,
    				PitchMultiplier = 1.0f
    			};
    
    			speechSynthesizer.SpeakUtterance (speechUtterance);
    		}
    	}
    }
    

    Phần quạn trong nhất trong project này là class TextToSpeech_iOS, đây là class thực thi interface ITextToSpeech, và được viết bằng code được thù của iOS, ví dụ như AVSpeechSynthesizer.

    • UsingDependencyService.Android
    using Android.Speech.Tts;
    using Xamarin.Forms;
    using UsingDependencyService.Android;
    using System.Diagnostics;
    
    [assembly: Dependency(typeof(TextToSpeech_Android))]
    namespace UsingDependencyService.Android
    {
        public class TextToSpeech_Android : Java.Lang.Object, ITextToSpeech, TextToSpeech.IOnInitListener
        {
            TextToSpeech speaker;
            string toSpeak;
    
            public void Speak(string text)
            {
                toSpeak = text;
                if (speaker == null)
                {
                    speaker = new TextToSpeech(Forms.Context, this);
                }
                else
                {
                    speaker.Speak(toSpeak, QueueMode.Flush, null, null);
                    Debug.WriteLine("spoke " + toSpeak);
                }
            }
    
            #region IOnInitListener implementation
            public void OnInit(OperationResult status)
            {
                if (status.Equals(OperationResult.Success))
                {
                    Debug.WriteLine("speaker init");
                    speaker.Speak(toSpeak, QueueMode.Flush, null, null);
                }
                else
                {
                    Debug.WriteLine("was quiet");
                }
            }
            #endregion
        }
    }
    
    

    Cũng giống iOS thì đoạn code trên được viết ở trong project Android, và thực thi interface ITextToSpeech trên nền tảng Android.
    Nguồn: Viblo


Hãy đăng nhập để trả lời
 

Có vẻ như bạn đã mất kết nối tới LaptrinhX, vui lòng đợi một lúc để chúng tôi thử kết nối lại.