Introducción a DependencyServiceIntroduction to DependencyService

Información generalOverview

DependencyService permite que las aplicaciones llamar a funciones específicas de plataforma desde código compartido.DependencyService allows apps to call into platform-specific functionality from shared code. Esta funcionalidad permite que las aplicaciones de Xamarin.Forms todo lo que puede hacer una aplicación nativa hacer.This functionality enables Xamarin.Forms apps to do anything that a native app can do.

DependencyService es un localizador de servicio.DependencyService is a service locator. En la práctica, se define una interfaz y DependencyService busca la correcta implementación de la interfaz de los diversos proyectos de plataforma.In practice, an interface is defined and DependencyService finds the correct implementation of that interface from the various platform projects.

Nota

De forma predeterminada, el DependencyService solucionará solo las implementaciones de plataforma que tienen constructores sin parámetros.By default, the DependencyService will only resolve platform implementations that have parameterless constructors. Sin embargo, un método de resolución de dependencia puede insertarse en Xamarin.Forms que usa un contenedor de inserción de dependencia o métodos de generador para resolver las implementaciones de plataforma.However, a dependency resolution method can be injected into Xamarin.Forms that uses a dependency injection container or factory methods to resolve platform implementations. Este enfoque puede utilizarse para resolver las implementaciones de plataforma que tienen constructores con parámetros.This approach can be used to resolve platform implementations that have constructors with parameters. Para obtener más información, consulte resolución de dependencias en Xamarin.Forms.For more information, see Dependency resolution in Xamarin.Forms.

Funcionamiento de DependencyServiceHow DependencyService Works

Las aplicaciones de Xamarin.Forms necesitan cuatro componentes que se utilizará DependencyService:Xamarin.Forms apps need four components to use DependencyService:

  • Interfaz – se define la funcionalidad requerida por una interfaz en código compartido.Interface – The required functionality is defined by an interface in shared code.
  • Implementación por plataforma – las clases que implementan la interfaz deben agregarse a cada proyecto de la plataforma.Implementation Per Platform – Classes that implement the interface must be added to each platform project.
  • Registro – cada clase de implementación debe registrarse con DependencyService a través de un atributo de metadatos.Registration – Each implementing class must be registered with DependencyService via a metadata attribute. Habilita el registro DependencyService para buscar la clase de implementación y proporcionar en lugar de la interfaz en tiempo de ejecución.Registration enables DependencyService to find the implementing class and supply it in place of the interface at run time.
  • La llamada a DependencyService – comparten el código debe llamar explícitamente a DependencyService para solicitar las implementaciones de la interfaz.Call to DependencyService – Shared code needs to explicitly call DependencyService to ask for implementations of the interface.

Tenga en cuenta que se deben proporcionar implementaciones para cada proyecto de la plataforma en la solución.Note that implementations must be provided for each platform project in your solution. Proyectos de la plataforma sin implementaciones se producirá un error en tiempo de ejecución.Platform projects without implementations will fail at runtime.

Se explica la estructura de la aplicación en el diagrama siguiente:The structure of the application is explained by the following diagram:

InterfazInterface

La interfaz de diseño que definirá cómo interactuar con una funcionalidad específica de la plataforma.The interface you design will define how you interact with platform-specific functionality. Tenga cuidado si está desarrollando un componente compartido como un componente o paquete de NuGet.Be careful if you are developing a component to be shared as a component or NuGet package. Diseño de API puede crear o interrumpir un paquete.API design can make or break a package. El ejemplo siguiente especifica una interfaz sencilla para hablar el texto que permite flexibilidad para especificar las palabras que se hablará, pero deja la implementación para personalizarse para cada plataforma:The example below specifies a simple interface for speaking text that allows for flexibility in specifying the words to be spoken but leaves the implementation to be customized for each platform:

public interface ITextToSpeech {
    void Speak ( string text ); //note that interface members are public by default
}

Implementación por plataformaImplementation per Platform

Una vez que se ha diseñado una interfaz adecuada, se debe implementar esa interfaz en el proyecto para cada plataforma de destino.Once a suitable interface has been designed, that interface must be implemented in the project for each platform that you are targeting. Por ejemplo, la siguiente clase implementa la ITextToSpeech interfaz en iOS:For example, the following class implements the ITextToSpeech interface on iOS:

namespace UsingDependencyService.iOS
{
    public class TextToSpeech_iOS : ITextToSpeech
    {
        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);
        }
    }
}

RegistroRegistration

Cada implementación de la interfaz debe estar registrada con DependencyService con un atributo de metadatos.Each implementation of the interface needs to be registered with DependencyService with a metadata attribute. El código siguiente registra la implementación para iOS:The following code registers the implementation for iOS:

[assembly: Dependency (typeof (TextToSpeech_iOS))]
namespace UsingDependencyService.iOS
{
  ...
}

En resumen, la implementación específica de la plataforma tiene este aspecto:Putting it all together, the platform-specific implementation looks like this:

[assembly: Dependency (typeof (TextToSpeech_iOS))]
namespace UsingDependencyService.iOS
{
    public class TextToSpeech_iOS : ITextToSpeech
    {
        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);
        }
    }
}

Nota: que se realiza el registro en el nivel de espacio de nombres, no en el nivel de clase.Note: that the registration is performed at the namespace level, not the class level.

Compilación nativa de .NET de plataforma de Windows universalUniversal Windows Platform .NET Native Compilation

Los proyectos UWP que usan la opción de compilación .NET Native deben seguir un configuración ligeramente diferentes al inicializar Xamarin.Forms.UWP projects that use the .NET Native compilation option should follow a slightly different configuration when initializing Xamarin.Forms. Compilación nativa de .NET también requiere el registro ligeramente diferente para los servicios de dependencia..NET Native compilation also requires slightly different registration for dependency services.

En el App.xaml.cs de archivos, registrar manualmente cada servicio de dependencia definida en el proyecto UWP con el Register<T> método tal y como se muestra a continuación:In the App.xaml.cs file, manually register each dependency service defined in the UWP project using the Register<T> method, as shown below:

Xamarin.Forms.Forms.Init(e, assembliesToInclude);
// register the dependencies in the same
Xamarin.Forms.DependencyService.Register<TextToSpeechImplementation>();

Nota: el registro manual mediante Register<T> es eficaz solo en la versión compilaciones con compilación nativa. NET.Note: manual registration using Register<T> is only effective in Release builds using .NET Native compilation. Si se omite esta línea, las compilaciones de depuración seguirá funcionando, pero compilaciones de versión se producirá un error al cargar el servicio de dependencia.If you omit this line, Debug builds will still work, but Release builds will fail to load the dependency service.

La llamada a DependencyServiceCall to DependencyService

Una vez que el proyecto se configuró con una interfaz común e implementaciones para cada plataforma, use DependencyService para obtener una implementación correcta en tiempo de ejecución:Once the project has been set up with a common interface and implementations for each platform, use DependencyService to get the right implementation at runtime:

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

DependencyService.Get<T> Encontrará la correcta implementación de interfaz T.DependencyService.Get<T> will find the correct implementation of interface T.

Estructura de la soluciónSolution Structure

El UsingDependencyService solución de ejemplo es que se muestra a continuación para iOS y Android, con los cambios de código descritos anteriormente resaltado.The sample UsingDependencyService solution is shown below for iOS and Android, with the code changes outlined above highlighted.

iOS y Android solucióniOS and Android solution

Nota

Le debe proporcionar una implementación en cada proyecto de la plataforma.You must provide an implementation in every platform project. Si no se registra ninguna implementación de interfaz, el DependencyService será no se puede resolver el Get<T>() método en tiempo de ejecución.If no Interface implementation is registered, then the DependencyService will be unable to resolve the Get<T>() method at runtime.