DependencyService 소개Introduction to DependencyService

샘플 다운로드 샘플 다운로드Download Sample Download the sample

개요Overview

DependencyService를 사용하면 애플리케이션이 공유 코드에서 플랫폼별 기능을 호출할 수 있습니다.DependencyService allows apps to call into platform-specific functionality from shared code. 이 기능을 통해 Xamarin.Forms 애플리케이션에서 네이티브 애플리케이션의 모든 작업을 수행할 수 있습니다.This functionality enables Xamarin.Forms apps to do anything that a native app can do.

DependencyService는 서비스 로케이터입니다.DependencyService is a service locator. 실제로 인터페이스가 정의되고 DependencyService가 다양한 플랫폼 프로젝트에서 해당 인터페이스의 올바른 구현을 찾습니다.In practice, an interface is defined and DependencyService finds the correct implementation of that interface from the various platform projects.

참고

기본적으로 DependencyService는 매개 변수가 없는 생성자가 있는 플랫폼 구현만 확인합니다.By default, the DependencyService will only resolve platform implementations that have parameterless constructors. 그러나 종속성 확인 메서드는 종속성 주입 컨테이너 또는 팩터리 메서드를 사용하여 플랫폼 구현을 확인하는 Xamarin.Forms에 주입할 수 있습니다.However, a dependency resolution method can be injected into Xamarin.Forms that uses a dependency injection container or factory methods to resolve platform implementations. 이 방법은 매개 변수가 있는 생성자가 있는 가진 플랫폼 구현을 확인하는 데 사용할 수 있습니다.This approach can be used to resolve platform implementations that have constructors with parameters. 자세한 내용은 Xamarin.Forms에서 종속성 확인을 참조하세요.For more information, see Dependency resolution in Xamarin.Forms.

DependencyService의 작동 방식How DependencyService Works

Xamarin.Forms 애플리케이션에서 DependencyService를 사용하는 데 필요한 네 가지 구성 요소는 다음과 같습니다.Xamarin.Forms apps need four components to use DependencyService:

  • 인터페이스 – 필요한 기능은 공유 코드의 인터페이스에서 정의됩니다.Interface – The required functionality is defined by an interface in shared code.
  • 플랫폼별 구현 – 인터페이스를 구현하는 각 클래스는 각 플랫폼 프로젝트에 추가해야 합니다.Implementation Per Platform – Classes that implement the interface must be added to each platform project.
  • 등록 – 각 구현 클래스는 메타데이터 특성을 통해 DependencyService에 등록해야 합니다.Registration – Each implementing class must be registered with DependencyService via a metadata attribute. DependencyService에서 등록을 통해 실행 클래스를 찾아 런타임에 인터페이스 대신 이를 제공할 수 있습니다.Registration enables DependencyService to find the implementing class and supply it in place of the interface at run time.
  • DependencyService 호출 – 공유 코드에서 DependencyService를 명시적으로 호출하여 인터페이스의 구현을 요청해야 합니다.Call to DependencyService – Shared code needs to explicitly call DependencyService to ask for implementations of the interface.

솔루션에서 각 플랫폼 프로젝트에 대한 구현을 제공해야 합니다.Note that implementations must be provided for each platform project in your solution. 구현이 없는 플랫폼 프로젝트는 런타임에 실패하게 됩니다.Platform projects without implementations will fail at runtime.

애플리케이션의 구조는 다음 다이어그램과 같습니다.The structure of the application is explained by the following diagram:

인터페이스Interface

설계하는 인터페이스는 플랫폼별 기능과 상호 작용하는 방법을 정의합니다.The interface you design will define how you interact with platform-specific functionality. 구성 요소 또는 NuGet 패키지로 공유할 구성 요소를 개발하는 경우 주의하세요.Be careful if you are developing a component to be shared as a component or NuGet package. API 디자인은 패키지를 만들거나 손상시킬 수 있습니다.API design can make or break a package. 아래의 예제에서는 말하는 단어를 유연하게 지정할 수 있는 간단한 텍스트 말하기 인터페이스를 지정하지만 각 플랫폼에 맞게 구현을 사용자 지정할 수 있는 상태로 둡니다.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
}

플랫폼별 구현Implementation per Platform

적절한 인터페이스가 설계되면 해당 인터페이스가 대상으로 하는 각 플랫폼에 맞게 프로젝트에 구현되어야 합니다.Once a suitable interface has been designed, that interface must be implemented in the project for each platform that you are targeting. 예를 들어 다음 클래스는 iOS에서 ITextToSpeech 인터페이스를 구현합니다.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);
        }
    }
}

등록Registration

인터페이스의 각 구현은 메타데이터 특성을 사용하여 DependencyService에 등록해야 합니다.Each implementation of the interface needs to be registered with DependencyService with a metadata attribute. iOS에 대한 구현을 등록하는 코드는 다음과 같습니다.The following code registers the implementation for iOS:

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

이를 모두 결합한 플랫폼별 구현은 다음과 같습니다.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);
        }
    }
}

참고: 등록은 클래스 수준이 아니라 네임스페이스 수준에서 수행됩니다.Note: that the registration is performed at the namespace level, not the class level.

유니버설 Windows 플랫폼 .NET 네이티브 컴파일Universal Windows Platform .NET Native Compilation

.NET 네이티브 컴파일 옵션을 사용하는 UWP 프로젝트는 Xamarin.Forms를 초기화할 때 약간 다른 구성을 따라야 합니다.UWP projects that use the .NET Native compilation option should follow a slightly different configuration when initializing Xamarin.Forms. 또한 .NET 네이티브 컴파일에는 종속성 서비스에 대해 약간 다른 등록이 필요합니다..NET Native compilation also requires slightly different registration for dependency services.

App.xaml.cs 파일에서 아래와 같이 Register<T> 메서드를 사용하여 UWP 프로젝트에 정의된 각 종속성 서비스를 수동으로 등록합니다.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>();

참고: Register<T>를 사용하는 수동 등록은 .NET 네이티브 컴파일을 사용하는 릴리스 빌드에서만 적용됩니다.Note: manual registration using Register<T> is only effective in Release builds using .NET Native compilation. 이 줄을 생략하면 디버그 빌드는 계속 작동하지만 릴리스 빌드는 종속성 서비스를 로드하지 못합니다.If you omit this line, Debug builds will still work, but Release builds will fail to load the dependency service.

DependencyService 호출Call to DependencyService

프로젝트가 각 플랫폼에 대한 공통 인터페이스 및 구현으로 설정되면 DependencyService를 사용하여 런타임에 올바른 구현을 가져올 수 있습니다.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>에서 T 인터페이스의 올바른 구현을 찾습니다.DependencyService.Get<T> will find the correct implementation of interface T.

솔루션 구조Solution Structure

위에서 설명한 코드 변경 내용이 강조 표시된 iOS 및 Android용 UsingDependencyService 솔루션 샘플은 아래와 같습니다.The sample UsingDependencyService solution is shown below for iOS and Android, with the code changes outlined above highlighted.

iOS 및 Android 솔루션iOS and Android solution

참고

모든 플랫폼 프로젝트에서 구현을 제공해야 합니다.You must provide an implementation in every platform project. 등록된 인터페이스 구현이 없으면 DependencyService에서 런타임에 Get<T>() 메서드를 확인할 수 없습니다.If no Interface implementation is registered, then the DependencyService will be unable to resolve the Get<T>() method at runtime.