Esercizio - Aggiungere un'astrazione e un localizzatore di servizi al progetto per trovare e usare una funzionalità specifica della piattaforma
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.
Aprire il progetto iniziale GreatQuotes.sln o continuare l'esercizio precedente.
Creare un nuovo file di origine dell'interfaccia nel progetto
GreatQuotes
. Denominarlo ITextToSpeech.cs.Rendere pubblica l'interfaccia in modo che possa essere usata all'esterno della libreria .NET Standard.
Aggiungere all'interfaccia un metodo denominato
Speak
, che restituiscevoid
e accetta un unico parametrostring
.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.
- Il codice si trova nella cartella exercise2>assets. Aggiungere la classe
ServiceLocator
nel progettoGreatQuotes
. Assicurarsi di copiare il file nel progetto anziché spostarlo. - 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.
- Una proprietà statica
Registrare le astrazioni con il localizzatore di servizi
Registrare le implementazioni per la funzionalità di sintesi vocale in ogni progetto specifico della piattaforma.
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.
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.
È 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'interfacciaITextToSpeech
.Per associare la classe
TextToSpeechService
all'interfacciaITextToSpeech
, usare il metodoAdd
sulServiceLocator
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>();
- Registrare la versione iOS nel file AppDelegate.cs come parte di
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.
Aggiungere un metodo alla classe condivisa
QuoteManager.cs
che richiamerà il servizio di sintesi vocale.Denominare il metodo
SayQuote
e fare in modo che accetti un parametroGreatQuote
.Cercare l'astrazione
ITextToSpeech
usando il metodoResolve
del localizzatore di servizi.Assicurarsi che il valore restituito non sia
null
. Se il valore non ènull
, usare il metodoSpeak
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
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 aggiungereTapGestureRecognizer
all'etichetta del testo della citazione e impostareNumberOfTapsRequired
sul valore uno.Creare un gestore per l'evento
Tapped
diTapGestureRecognizer
.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>
A questo punto è necessario aggiornare il metodo
Handle_Tapped
nella classeQuoteDetailPage
. Prima di tutto, occorre considerare in che modo si intende strutturare il codice.QuoteManager
è una dipendenza della classeMainViewModel
ed è responsabile della gestione delle citazioni.MainViewModel
è disponibile come proprietà statica ed espone già un metodoSave
per consentire il salvataggio di una citazione. Si seguirà lo stesso schema, in modo che le citazioni possono essere pronunciate.Aprire la classe
MainViewModel
e aggiungere un metodo denominatoSayQuotes
. Questo metodo accettaGreatQuoteViewModel
come parametro. Dal metodo, chiamare il metodoquoteManager.SayQuote
e passargli la citazione.Il codice del metodo dovrebbe essere simile al seguente:
public void SayQuotes(GreatQuoteViewModel quote) { quoteManager.SayQuote(quote); }
Infine, nel metodo
Handle_Tapped
diQuoteDetailPage
fare riferimento aApp.GreatQuotesViewModel
e chiamare il metodoSayQuotes
. Eseguire il cast delBindingContext
della pagina comeGreatQuoteViewModel
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
- Compilare ed eseguire l'applicazione nel maggior numero di implementazioni possibili.
- 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.