# Getting Started | WPF Controls | DevExpress Documentation

A Service is a special [Behavior](/WPF/17442/mvvm-framework/behaviors) that implements an interface. Although Services are defined in Xaml, the Service interfaces can be accessed from the View Model layer.

## Implement Services in Your Application

Follow the steps below to use Services.

- Set the View’s DataContext to your View Model.
- Define a service in XAML.
- Get access to the service’s interface from your View Model via the **GetService&lt;T&gt;** method.

### Example

Assume that you need to show a message box from a View Model. The easiest way to accomplish this task is to use the **MessageBox.Show** method directly from the View Model. However, this approach breaks the main MVVM rule: the View Model layer should not refer to the View layer. Thus, this way makes it impossible to write unit tests for this View Model, because there is no one who can click the MessageBox button during a unit test. For solving such tasks in MVVM, use the Services mechanism.

Let’s discuss how to solve the posed task with Services. We have the following View Model…

- C#

<section id="tabpanel_tOMLmkQJrO_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class DocumentViewModel : ViewModelBase {
    public ICommand CloseDocumentCommand { get; private set; }
    public DocumentViewModel() {
        CloseDocumentCommand = new DelegateCommand(CloseDocument);
    }
    void CloseDocument() {
        MessageBoxResult canCloseDocument;
        //canCloseDocument = 
            //    MessageBox.Show(&quot;Want to save your changes?&quot;, &quot; Document&quot;, MessageBoxButton.YesNoCancel);
        if(canCloseDocument == MessageBoxResult.Yes) {
            //...
        }
    }
}
</code></pre></section>

… and the following View:

- XAML

<section id="tabpanel_tOMLmkQJrO-1_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;UserControl x:Class=&quot;Example.View.DocumentView&quot;
    xmlns:ViewModel=&quot;clr-namespace:Example.ViewModel&quot; ...&gt;
    &lt;UserControl.DataContext&gt;
        &lt;ViewModel:DocumentViewModel/&gt;
    &lt;/UserControl.DataContext&gt;
    ...
        &lt;Button Content=&quot;Close Document&quot; Command=&quot;{Binding CloseDocumentCommand}&quot; .../&gt;
    ...
&lt;/UserControl&gt;
</code></pre></section>

The DevExpress.Xpf.Mvvm library provides the **IMessageBoxService** interface. Implementation of this interface is contained in the DevExpress.Xpf.Core library – the **DXMessageBoxService** class. To add this service to our View (DocumentView), add it to the **Interaction.Behaviors** collection as follows.

- XAML

<section id="tabpanel_tOMLmkQJrO-2_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;UserControl x:Class=&quot;Example.View.DocumentView&quot;
    xmlns:dx=&quot;http://schemas.devexpress.com/winfx/2008/xaml/core&quot;
    xmlns:dxmvvm=&quot;http://schemas.devexpress.com/winfx/2008/xaml/mvvm&quot;
    xmlns:ViewModel=&quot;clr-namespace:Example.ViewModel&quot; ...&gt;
    &lt;UserControl.DataContext&gt;
        &lt;ViewModel:DocumentViewModel/&gt;
    &lt;/UserControl.DataContext&gt;
    &lt;dxmvvm:Interaction.Behaviors&gt;
        &lt;dx:DXMessageBoxService/&gt;
    &lt;/dxmvvm:Interaction.Behaviors&gt;
    ...
        &lt;Button Content=&quot;Close Document&quot; Command=&quot;{Binding CloseDocumentCommand}&quot; .../&gt;
    ...
&lt;/UserControl&gt;
</code></pre></section>

Services are automatically injected to View Models, so they are available from there via an interface that is provided by a certain service.

As you may have noticed, our View Model (DocumentViewModel) is inherited from the [ViewModelBase](/WPF/17351/mvvm-framework/viewmodels/viewmodelbase) class. So, the DocumentViewModel supports the **GetService&lt;T&gt;** method that returns an interface used to access the DXMessageBoxService.

- C#

<section id="tabpanel_tOMLmkQJrO-3_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class DocumentViewModel : ViewModelBase {
    public ICommand CloseDocumentCommand { get; private set; }
    public IMessageBoxService MessageBoxService { get { return GetService&lt;IMessageBoxService&gt;(); } }
    ...
    void CloseDocument() {
        MessageBoxResult canCloseDocument = MessageBoxService.Show(
            messageBoxText: &quot;Want to save your changes?&quot;, 
            caption: &quot;Document&quot;, 
            button: MessageBoxButton.YesNoCancel);
        if(canCloseDocument == MessageBoxResult.Yes) {
            //...
        }
    }
}
</code></pre></section>

### Access Services

View Models can access services from the following sources:

- From a View that uses this View Model as a `DataContext`.
- From a parent View Model specified as demonstrated in the following topic: [ViewModel relationships (ISupportParentViewModel)](/WPF/17449/mvvm-framework/viewmodels/viewmodel-relationships-isupportparentviewmodel).

Services become available after the View (to which these services are attached) is loaded. To obtain services and perform preliminary actions, handle the View’s **Loaded** event (you can use the [EventToCommand](/WPF/DevExpress.Mvvm.UI.EventToCommand) behavior) and access the service. The following code sample uses the [FrameNavigationService](/WPF/DevExpress.Xpf.WindowsUI.Navigation.FrameNavigationService) to navigate to the **HomeView** once the control is loaded:

- XAML

<section id="tabpanel_tOMLmkQJrO-4_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;UserControl x:Class=&quot;DXSample.View.MainView&quot; 
    ... 
    DataContext=&quot;{dxmvvm:ViewModelSource Type={x:Type ViewModel:MainViewModel}}&quot;&gt;
    &lt;Grid&gt;
        &lt;dxwui:NavigationFrame AnimationType=&quot;SlideHorizontal&quot;&gt;
            &lt;dxmvvm:Interaction.Behaviors&gt;
                &lt;dxmvvm:EventToCommand EventName=&quot;Loaded&quot; Command=&quot;{Binding OnViewLoadedCommand}&quot; /&gt;
                &lt;dxwuin:FrameNavigationService /&gt;
            &lt;/dxmvvm:Interaction.Behaviors&gt;
        &lt;/dxwui:NavigationFrame&gt;
    &lt;/Grid&gt;
&lt;/UserControl&gt;
</code></pre></section>

- C#

<section id="tabpanel_tOMLmkQJrO-5_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class MainViewModel {
    private INavigationService NavigationService { get { return this.GetService&lt;INavigationService&gt;(); } }

    public MainViewModel() {  }

    public void OnViewLoaded() {
        NavigationService.Navigate(&quot;HomeView&quot;, null, this);
    }
}
</code></pre></section>

### Identify Services by Their Names

You can define multiple instances of a service with different settings. Specify the service `Name` property and use the [GetService&lt;T&gt;(String, ServiceSearchMode)](/CoreLibraries/DevExpress.Mvvm.ServiceContainer.GetService--1%28System.String-DevExpress.Mvvm.ServiceSearchMode%29) method overload to identify these services in the View Model:

- XAML

<section id="tabpanel_tOMLmkQJrO-6_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;dxmvvm:Interaction.Behaviors&gt;
    &lt;dx:DXMessageBoxService x:Name=&quot;TextMessageBox&quot; AllowTextSelection=&quot;True&quot;/&gt;
    &lt;dx:DXMessageBoxService x:Name=&quot;MessageBox&quot;/&gt;
&lt;/dxmvvm:Interaction.Behaviors&gt;
&lt;Window.DataContext&gt;
    &lt;local:MainViewModel/&gt;
&lt;/Window.DataContext&gt;
&lt;Grid&gt;
    &lt;Button Content=&quot;Show Text Message&quot; Command=&quot;{Binding ShowTextMessageCommand}&quot;/&gt;
    &lt;Button Content=&quot;Show Message&quot; Command=&quot;{Binding ShowMessageCommand}&quot;/&gt;
&lt;/Grid&gt;
</code></pre></section>

- C#

<section id="tabpanel_tOMLmkQJrO-7_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class MainViewModel : ViewModelBase {
    public IMessageBoxService TextMessageBoxService { get { return GetService&lt;IMessageBoxService&gt;(&quot;TextMessageBox&quot;); } }
    public IMessageBoxService MessageBoxService { get { return GetService&lt;IMessageBoxService&gt;(&quot;MessageBox&quot;); } }
    [Command]
    public void ShowTextMessage() {
        TextMessageBoxService.ShowMessage(&quot;You can select parts of this text&quot;);
    }
    [Command]
    public void ShowMessage() {
        MessageBoxService.ShowMessage(&quot;Message text&quot;);
    }
}
</code></pre></section>

### Create Unit Tests

The use of Services makes it easy to create unit-tests for your View Models. Let’s write a test for the above-mentioned DocumentViewModel ([Moq Library](https://github.com/devlooped/moq) is used).

- C#

<section id="tabpanel_tOMLmkQJrO-8_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">[TestFixture]
public class DocumentViewModelTests {
    [Test]
    public void Test() {
        bool serviceIsCalled = false;
        var viewModel = new DocumentViewModel();
        var service = new Mock&lt;IMessageBoxService&gt;(MockBehavior.Strict);
        service.
           Setup(foo =&gt; foo.Show(
               &quot;Want to save your changes?&quot;, &quot;Document&quot;, MessageBoxButton.YesNoCancel, 
                MessageBoxImage.None, MessageBoxResult.None)).
           Returns((string text, string caption, MessageBoxButton button,
                MessageBoxImage image, MessageBoxResult none) =&gt; {
               serviceIsCalled = true;
               return MessageBoxResult.OK;
           });
        ((ISupportServices)viewModel).ServiceContainer.RegisterService(service.Object);
        viewModel.CloseDocumentCommand.Execute(null);
        Assert.IsTrue(serviceIsCalled);
    }
}
</code></pre></section>

Note

Refer to the following topic for a tutorial and a downloadable example: [DXMessageBoxService](/WPF/17415/mvvm-framework/services/predefined-set/message-box-services/dxmessageboxservice).

## Use Services with Dependency Injection

The recommended technique to use DevExpress services with Dependency Injection varies depending on whether the service has an associated visual element.

- If the service is attached to a specific visual element, add the following custom **AttachServiceBehavior** to register it:

- C#

<section id="tabpanel_tOMLmkQJrO-9_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class AttachServiceBehavior : Behavior&lt;DependencyObject&gt; {
    public static readonly DependencyProperty AtachableServiceProperty =
        DependencyProperty.Register(nameof(AtachableService), typeof(ServiceBase),
        typeof(AttachServiceBehavior), new PropertyMetadata(null, OnAtachableServiceChanged));

    static void OnAtachableServiceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        (e.OldValue as ServiceBase)?.Detach();
        ((AttachServiceBehavior)d).AttachService();
    }
    public ServiceBase AtachableService {
        get =&gt; (ServiceBase)GetValue(AtachableServiceProperty);
        set =&gt; SetValue(AtachableServiceProperty, value);
    }

    protected override void OnAttached() {
        base.OnAttached();
        AttachService();
    }
    protected override void OnDetaching() {
        base.OnDetaching();
        AtachableService?.Detach();
    }

    void AttachService() {
        if(AtachableService == null || AssociatedObject == null)
            return;
        if(AtachableService.IsAttached)
            AtachableService.Detach();
        AtachableService.Attach(AssociatedObject);
    }
}
</code></pre></section>

      Add a public property that corresponds to the service to the View Model:

- C#

<section id="tabpanel_tOMLmkQJrO-10_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class MainViewModel {
    public INavigationService NavigationService { get; }

    public MainViewModel(INavigationService navigationService) =&gt;
        NavigationService = navigationService;
}
</code></pre></section>

      Use the **AttachServiceBehavior** to attach the service to a visual element: 

- XAML

<section id="tabpanel_tOMLmkQJrO-11_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;dxwui:NavigationFrame&gt;
    &lt;dxmvvm:Interaction.Behaviors&gt;
        &lt;common:AttachServiceBehavior Service=&quot;{Binding NavigationService}&quot;/&gt;
    &lt;/dxmvvm:Interaction.Behaviors&gt;
&lt;/dxwui:NavigationFrame&gt;
</code></pre></section>

      [View Example](https://github.com/DevExpress-Examples/wpf-mvvm-framework-use-services-with-dependency-injection)
- If the service does not need to be attached to a specific visual element (such as [Message Box Services](/WPF/113933/mvvm-framework/services/predefined-set/message-box-services)), you can use the following technique instead:

    1. Register the service in the Dependency Injection container:

- C#

<section id="tabpanel_tOMLmkQJrO-12_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">container.RegisterSingleton(typeof(IMessageBoxService), typeof(DXMessageBoxService));
</code></pre></section>
    2. Specify the corresponding View Model property:

- C#

<section id="tabpanel_tOMLmkQJrO-13_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class MainViewModel {
    IMessageBoxService messageBoxService;
    public MainViewModel(IMessageBoxService dialogService) {
        this.messageBoxService = messageBoxService;
    }
}
</code></pre></section>

Tip

If you configure the service to work with a specific View, Dependency Injection is not recommended. Use the technique described in the **Implement Services in Your Application** section.

## Register Services at App.xaml

Use the **DevExpress.Mvvm.ServiceContainer.Default** property to access application services at the View level.

- C#

<section id="tabpanel_tOMLmkQJrO-14_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">ServiceContainer.Default.GetService&lt;IDispatcherService&gt;();
</code></pre></section>

You can register services that are not associated with a specific control (for example, NotificationService or DispatcherService) at the App.xaml.

- Xaml

<section id="tabpanel_tOMLmkQJrO-15_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;Application.Resources&gt;
    &lt;dx:DXMessageBoxService x:Key=&quot;MessageBoxService&quot;/&gt;
&lt;/Application.Resources&gt;
</code></pre></section>

You can access services registered at the App.xaml only from the UI thread.