Back to Devexpress

Services in Custom ViewModels

wpf-17450-mvvm-framework-services-services-in-custom-viewmodels.md

latest6.4 KB
Original Source

Services in Custom ViewModels

  • Apr 15, 2021
  • 4 minutes to read

This documentation topic describes how you can implement support of the Service mechanism in a custom View Model (not derived from the ViewModelBase class and not a POCO ViewModel).

If your View Model is not a POCO View Model and it is not derived from the ViewModelBase class, you can still use the Service mechanism. To implement Service support, implement the ISupportServices interface in your View Model.

The ISupportServices interface is shown below.

csharp
public interface ISupportServices {
    IServiceContainer ServiceContainer { get; }
}
vb
Public Interface ISupportServices
    ReadOnly Property ServiceContainer() As IServiceContainer
End Interface

To implement the ISupportServices interface, use the following construction.

csharp
public class ViewModel : ISupportServices {
    IServiceContainer serviceContainer = null;
    protected IServiceContainer ServiceContainer {
        get {
            if(serviceContainer == null)
                serviceContainer = new ServiceContainer(this);
            return serviceContainer; 
        }
    }
    IServiceContainer ISupportServices.ServiceContainer { get { return ServiceContainer; } }
}
vb
Public Class ViewModel
    Implements ISupportServices
    Private m_serviceContainer As IServiceContainer = Nothing
    Protected ReadOnly Property ServiceContainer() As IServiceContainer
        Get
            If m_serviceContainer Is Nothing Then
                m_serviceContainer = New ServiceContainer(Me)
            End If
            Return m_serviceContainer
        End Get
    End Property
    Private ReadOnly Property ISupportServices_ServiceContainer() As IServiceContainer Implements ISupportServices.ServiceContainer
        Get
            Return ServiceContainer
        End Get
    End Property
End Class

The ServiceContainer class implements the IServiceContainer interface that provides methods for registering and accessing services.

The IServiceContainer interface is shown below.

csharp
public interface IServiceContainer {
    void Clear();
    T GetService<T>(ServiceSearchMode searchMode = ServiceSearchMode.PreferLocal) where T : class;
    T GetService<T>(string key, ServiceSearchMode searchMode = ServiceSearchMode.PreferLocal) where T : class;
    void RegisterService(object service);
    void RegisterService(string key, object service);
}
vb
Public Interface IServiceContainer
    Sub Clear()
    Function GetService(Of T As Class)(Optional searchMode As ServiceSearchMode = ServiceSearchMode.PreferLocal) As T
    Function GetService(Of T As Class)(key As String, Optional searchMode As ServiceSearchMode = ServiceSearchMode.PreferLocal) As T
    Sub RegisterService(service As Object)
    Sub RegisterService(key As String, service As Object)
End Interface

When Services (derived from the ServiceBase class) are registered in a View, they analyze their DataContext. If the DataContext is set to an ISupportServices object, a service registers itself within this object. This is accomplished by calling the IServiceContainer.RegisterService method on the ISupportServices.ServiceContainer object. Thus, the service becomes available for use within the ISupportServices object via the IServiceContainer.GetService<T> method.

The following code defines a command within a View Model that displays a message box via a dedicated Message Box service. The service is accessed via the GetService<T> method invoked on the View Model’s ServiceContainer protected property. The GetService method retrieves an actual service from a View that implements the specified IMessageBoxService interface.

csharp
public class ViewModel : ISupportServices {
    IServiceContainer serviceContainer = null;
    protected IServiceContainer ServiceContainer {
        get {
            if(serviceContainer == null)
                serviceContainer = new ServiceContainer(this);
            return serviceContainer; 
        }
    }
    IServiceContainer ISupportServices.ServiceContainer { get { return ServiceContainer; } }
    IMessageBoxService MessageBoxService { get { return ServiceContainer.GetService<IMessageBoxService>(); } }

    public ICommand ShowMessageCommand { get; private set; }
    public ViewModel() {
        ShowMessageCommand = new DelegateCommand(ShowMessage);
    }
    void ShowMessage() {
        MessageBoxService.Show("Hello");
    }
}
vb
Public Class ViewModel
    Implements ISupportServices
    Private m_serviceContainer As IServiceContainer = Nothing
    Protected ReadOnly Property ServiceContainer() As IServiceContainer
        Get
            If m_serviceContainer Is Nothing Then
                m_serviceContainer = New ServiceContainer(Me)
            End If
            Return m_serviceContainer
        End Get
    End Property
    Private ReadOnly Property ISupportServices_ServiceContainer() As IServiceContainer Implements ISupportServices.ServiceContainer
        Get
            Return ServiceContainer
        End Get
    End Property
    Private ReadOnly Property MessageBoxService() As IMessageBoxService
        Get
            Return ServiceContainer.GetService(Of IMessageBoxService)()
        End Get
    End Property

    Public Property ShowMessageCommand() As ICommand
        Get
            Return m_ShowMessageCommand
        End Get
        Private Set(value As ICommand)
            m_ShowMessageCommand = Value
        End Set
    End Property
    Private m_ShowMessageCommand As ICommand
    Public Sub New()
        ShowMessageCommand = New DelegateCommand(AddressOf ShowMessage)
    End Sub
    Private Sub ShowMessage()
        MessageBoxService.Show("Hello")
    End Sub
End Class

The following documentation topic contains an example that demonstrates how to support the ISupportService interface in a custom View Model and use services: DXMessageBoxService.