Esercizio - Aggiungere un'astrazione e un localizzatore di servizi al progetto per trovare e usare una funzionalità specifica della piattaforma

Completato

In questo esercizio si definirà un servizio di sintesi vocale. Si userà quindi un localizzatore di servizi per trovare l'implementazione del servizio specifico della piattaforma. Il servizio consentirà agli utenti di selezionare una citazione e ascoltarne la pronuncia nell'applicazione.

Nota

Il pacchetto NuGet Xamarin.Essentials include la funzionalità di sintesi vocale. Tale funzionalità si basa sulle stesse API che verranno usate qui, ma non richiede alcun codice specifico della piattaforma.

Questo esercizio è una continuazione dell'esercizio precedente. Usare la soluzione esistente come punto di partenza per questi passaggi. Per iniziare da qui, aprire la soluzione completata dalla cartella exercise1>final nella copia del repository dell'esercizio clonato o scaricato.

Usare un'interfaccia per creare l'astrazione del motore di sintesi vocale

Si inizierà definendo l'astrazione. Ogni piattaforma userà il proprio motore di sintesi vocale per leggere all'utente le citazioni archiviate. Innanzitutto, è necessario definire un'interfaccia denominata ITextToSpeech con un singolo metodo denominato Speak. L'interfaccia deve trovarsi nel codice condiviso. Verrà inserita nella libreria .NET Standard GreatQuotes.

  1. Aprire il progetto iniziale GreatQuotes.sln o continuare l'esercizio precedente.

  2. Creare un nuovo file di origine dell'interfaccia nel progetto GreatQuotes. Denominarlo ITextToSpeech.cs.

  3. Rendere pubblica l'interfaccia in modo che possa essere usata all'esterno della libreria .NET Standard.

  4. Aggiungere all'interfaccia un metodo denominato Speak, che restituisce void e accetta un unico parametro string.

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

Aggiungere un localizzatore di servizi

A questo punto, aggiungere un localizzatore di servizi. Per risparmiare tempo, aggiungere un'implementazione esistente.

  1. Il codice si trova nella cartella exercise2>assets. Aggiungere la classe ServiceLocator nel progetto GreatQuotes. Assicurarsi di copiare il file nel progetto anziché spostarlo.
  2. Esaminare il nuovo file di origine aggiunto. Associa un contratto Type con un'implementazione, salvando la registrazione in un dizionario.
    • Una proprietà statica Instance recupera l'oggetto Singleton del localizzatore.
    • Un metodo Add registra un tipo con un'implementazione.
    • Il metodo Resolve<T> individua un'implementazione in base all'astrazione.

Registrare le astrazioni con il localizzatore di servizi

Registrare le implementazioni per la funzionalità di sintesi vocale in ogni progetto specifico della piattaforma.

  1. Aggiungere le implementazioni del motore di sintesi vocale per ogni piattaforma. La cartella exercise2>assets contiene due implementazioni: una per iOS e una per Android.

  2. Aggiungere ogni implementazione al progetto specifico della piattaforma appropriato, in base al nome:

    • TextToSpeechService.Android.cs va nel progetto Android.
    • TextToSpeechService.iOS.cs va nel progetto iOS.
  3. È possibile esaminare l'origine per ogni implementazione. Verificare che l'interfaccia sia definita e implementata correttamente. Compilare i progetti.

    Usare ServiceLocator per registrare ogni implementazione nel codice della piattaforma con l'interfaccia ITextToSpeech.

  4. Per associare la classe TextToSpeechService all'interfaccia ITextToSpeech, usare il metodo Add sul ServiceLocator nel progetto specifico della piattaforma.

    • Registrare la versione iOS nel file AppDelegate.cs come parte di FinishedLaunching.
    • Registrare la versione di Android nel file MainActivity.cs come parte dell'override MainActivity.OnCreate.
    ServiceLocator.Instance.Add<ITextToSpeech, TextToSpeechService>();
    

Aggiornare la classe QuoteManager con il comportamento di sintesi vocale

Aggiungere il supporto per chiamare il servizio di sintesi vocale nel codice condiviso e richiamarlo da ogni piattaforma.

  1. Aggiungere un metodo alla classe condivisa QuoteManager.cs che richiamerà il servizio di sintesi vocale.

  2. Denominare il metodo SayQuote e fare in modo che accetti un parametro GreatQuote.

  3. Cercare l'astrazione ITextToSpeech usando il metodo Resolve del localizzatore di servizi.

  4. Assicurarsi che il valore restituito non sia null. Se il valore non è null, usare il metodo Speak per pronunciare la citazione e l'autore.

    public class QuoteManager
    {
        ...
        public void SayQuote(GreatQuoteViewModel quote)
        {
            if (quote == null)
                throw new ArgumentNullException("No quote set");
    
            ITextToSpeech tts = ServiceLocator.Instance.Resolve<ITextToSpeech>();
    
            if (tts != null)
            {
                var text = quote.QuoteText;
    
                if (!string.IsNullOrWhiteSpace(quote.Author))
                   text += $" by {quote.Author}";
    
                tts.Speak(text);
            }
        }
    }
    

Aggiornare la classe QuoteDetailPage con il comportamento di sintesi vocale

  1. Si aggiornerà QuoteDetailPage per consentire agli utenti di toccare una citazione e ascoltarne il testo letto dal motore di sintesi vocale. Nel codice XAML della pagina aggiungere TapGestureRecognizer all'etichetta del testo della citazione e impostare NumberOfTapsRequired sul valore uno.

  2. Creare un gestore per l'evento Tapped di TapGestureRecognizer.

    La dichiarazione XAML dell'etichetta dovrebbe avere un aspetto simile al seguente:

    <Label Grid.Row="1" Text="{Binding QuoteText}"
            VerticalOptions="Start"
            Style="{DynamicResource BodyStyle}">
        <Label.GestureRecognizers>
            <TapGestureRecognizer NumberOfTapsRequired="1" Tapped="Handle_Tapped" />
        </Label.GestureRecognizers>
    </Label>
    
  3. A questo punto è necessario aggiornare il metodo Handle_Tapped nella classe QuoteDetailPage. Prima di tutto, occorre considerare in che modo si intende strutturare il codice. QuoteManager è una dipendenza della classe MainViewModel ed è responsabile della gestione delle citazioni. MainViewModel è disponibile come proprietà statica ed espone già un metodo Save per consentire il salvataggio di una citazione. Si seguirà lo stesso schema, in modo che le citazioni possono essere pronunciate.

  4. Aprire la classe MainViewModel e aggiungere un metodo denominato SayQuotes. Questo metodo accetta GreatQuoteViewModel come parametro. Dal metodo, chiamare il metodo quoteManager.SayQuote e passargli la citazione.

    Il codice del metodo dovrebbe essere simile al seguente:

    public void SayQuotes(GreatQuoteViewModel quote)
    {
        quoteManager.SayQuote(quote);
    }
    
  5. Infine, nel metodo Handle_Tapped di QuoteDetailPage fare riferimento a App.GreatQuotesViewModel e chiamare il metodo SayQuotes. Eseguire il cast del BindingContext della pagina come GreatQuoteViewModel e passarlo come parametro del metodo.

    Il codice del metodo dovrebbe essere simile al seguente:

    void Handle_Tapped(object sender, System.EventArgs e)
    {
       App.GreatQuotesViewModel.SayQuotes(BindingContext as GreatQuoteViewModel);
    }
    

Eseguire l'applicazione

  1. Compilare ed eseguire l'applicazione nel maggior numero di implementazioni possibili.
  2. Impostare alcuni punti di interruzione e tracciare il localizzatore di servizi per vedere come trova l'implementazione e richiama il servizio.

È possibile visualizzare la soluzione completata nella cartella exercise2>final della copia del repository dell'esercizio clonato o scaricato.

In questo esercizio, è stato usato uno schema del localizzatore di servizi per astrarre una funzionalità specifica della piattaforma e quindi richiamarla dal codice condiviso.