Introducción a DependencyServiceIntroduction to DependencyService

Descargar ejemplo Descargar el ejemploDownload Sample Download the sample

Información generalOverview

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

DependencyService es un localizador de servicios.DependencyService is a service locator. En la práctica, se define una interfaz y DependencyService busca la implementación correcta de esa interfaz en 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, DependencyService solo resuelve implementaciones de plataforma con constructores sin parámetros.By default, the DependencyService will only resolve platform implementations that have parameterless constructors. Pero se puede incorporar a Xamarin.Forms un método de resolución de dependencias que use un contenedor de inserción de dependencias o métodos de generador para resolver 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 usarse 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, vea 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 para usar DependencyService:Xamarin.Forms apps need four components to use DependencyService:

  • Interfaz – una interfaz define la funcionalidad requerida en el 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 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. El registro permite a DependencyService buscar la clase de implementación y proporcionarla 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.
  • Llamada a DependencyService – el código compartido debe llamar de forma explícita 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 plataforma de la solución.Note that implementations must be provided for each platform project in your solution. Los proyectos de plataforma sin implementaciones experimentan un error en tiempo de ejecución.Platform projects without implementations will fail at runtime.

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

InterfazInterface

La interfaz diseñada define cómo se interactúa con la funcionalidad específica de la plataforma.The interface you design will define how you interact with platform-specific functionality. Sea cuidadoso en caso de estar desarrollando un componente para compartirlo como componente o paquete NuGet.Be careful if you are developing a component to be shared as a component or NuGet package. El diseño de la API puede crear o romper un paquete.API design can make or break a package. En el ejemplo siguiente se especifica una interfaz sencilla para texto oral que ofrece flexibilidad a la hora de especificar las palabras que se van a decir pero permite personalizar la implementación 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 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 interfaz ITextToSpeech 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 registrarse 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);
        }
    }
}

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

Compilación .NET Native de Plataforma universal de WindowsUniversal Windows Platform .NET Native Compilation

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

En el archivo App.xaml.cs, registre manualmente cada servicio de dependencia definido en el proyecto de UWP con el método Register<T>, 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>();

Observe que el registro manual mediante Register<T> solo es eficaz en las compilaciones de versión mediante compilación .NET Native.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 siguen funcionando, pero las compilaciones de versión no cargan el servicio de dependencia.If you omit this line, Debug builds will still work, but Release builds will fail to load the dependency service.

Llamada a DependencyServiceCall to DependencyService

Una vez que el proyecto se ha configurado con una interfaz común e implementaciones para cada plataforma, use DependencyService para obtener la 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> encuentra la implementación correcta de interfaz T.DependencyService.Get<T> will find the correct implementation of interface T.

Estructura de soluciónSolution Structure

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

Solución de iOS y AndroidiOS and Android solution

Nota

Debe proporcionar una implementación en cada proyecto de plataforma.You must provide an implementation in every platform project. Si no se registra ninguna implementación de interfaz, DependencyService no puede resolver el método Get<T>() 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.