Skip to main content
All docs
V26.1
  • Dependency Injection

    • 3 minutes to read

    Bind a View to a View Model

    Configure the application dependency injection container and assign it to the IocServiceProvider.Default service at startup. The IocExtension can resolve MainViewModel from XAML during initialization:

    using DevExpress.Mvvm;
    using Microsoft.Extensions.DependencyInjection;
    using MvvmApp.ViewModels;
    
    namespace MvvmApp {
        public partial class App : Application {
            // ...
            protected override void OnStartup(StartupEventArgs e) {
                IServiceProvider services = new ServiceCollection()
                    .AddTransient<MainViewModel>()
                    .BuildServiceProvider();
                // Configure the global provider before WPF starts loading StartupUri/XAML
                // The {dxmvvm:Ioc ...} config can resolve types in XAML during initialization
                IocServiceProvider.Default.ConfigureServices(services);
                base.OnStartup(e);
    
                var mainWindow = new MainWindow();
                MainWindow = mainWindow;
                mainWindow.Show();
            }
        }
    }
    

    Declare a MainViewModel class with a read-only Message property that contains text for UI binding:

    namespace MvvmApp.ViewModels {
        public sealed class MainViewModel {
            public string Message { get; } = "DI works through the IocExtension";
        }
    }
    

    Use the IocExtension to resolve a MainViewModel from the configured dependency injection container. The window sets the resolved MainViewModel instance as DataContext, so the TextBlock can bind to the Message property:

    <dx:ThemedWindow
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
        xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
        xmlns:vm="clr-namespace:MvvmApp.ViewModels"
    
        DataContext="{dxmvvm:Ioc Type={x:Type vm:MainViewModel}}">
    
        <Grid>
            <TextBlock Text="{Binding Message}"/>
        </Grid>
    </dx:ThemedWindow>
    

    Examples

    Services

    View Example: DevExpress MVVM Framework — Use DevExpress Services with a Dependency Injection

    POCO

    View Example: Register a POCO View Model in a Dependency Injection Container

    Use POCO View Models with Dependency Injection

    To use a POCO View Model in a dependency injection container, register the View Model type in the container:

    services.AddTransient(typeof(MainViewModel));
    

    View Example: Register a POCO View Model in a Dependency Injection Container

    Use Services with Dependency Injection

    We recommend two different DevExpress service usage techniques with dependency injection depending on whether the required service is associated with a visual element.

    Attached Service

    1. If the service is attached to a specific visual element, add the following custom AttachServiceBehavior:

      public class AttachServiceBehavior : Behavior<DependencyObject> {
          public static readonly DependencyProperty AttachableServiceProperty =
              DependencyProperty.Register(
                  nameof(AttachableService),
                  typeof(ServiceBase),
                  typeof(AttachServiceBehavior),
                  new PropertyMetadata(null, OnAttachableServiceChanged));
      
          static void OnAttachableServiceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
              (e.OldValue as ServiceBase)?.Detach();
              ((AttachServiceBehavior)d).AttachService();
          }
      
          public ServiceBase AttachableService {
              get => (ServiceBase)GetValue(AttachableServiceProperty);
              set => SetValue(AttachableServiceProperty, value);
          }
      
          protected override void OnAttached() {
              base.OnAttached();
              AttachService();
          }
          protected override void OnDetaching() {
              base.OnDetaching();
              AttachableService?.Detach();
          }
      
          void AttachService() {
              if(AttachableService == null || AssociatedObject == null)
                  return;
              if(AttachableService.IsAttached)
                  AttachableService.Detach();
              AttachableService.Attach(AssociatedObject);
          }
      }
      
    2. Add a public property that maps the service to the view model:

      public class MainViewModel {
          public INavigationService NavigationService { get; }
      
          public MainViewModel(INavigationService navigationService) =>
              NavigationService = navigationService;
      }
      
    3. Use the AttachServiceBehavior property to attach the service to a visual element:

      <dxwui:NavigationFrame>
          <dxmvvm:Interaction.Behaviors>
              <common:AttachServiceBehavior AttachableService="{Binding NavigationService}"/>
          </dxmvvm:Interaction.Behaviors>
      </dxwui:NavigationFrame>
      

      View Example: DevExpress MVVM Framework — Use DevExpress Services with a Dependency Injection

    Unattached Service

    1. If the service does not need to be attached to a specific visual element (such as Message Box Services), you can register the service in the dependency injection container:

      services.AddSingleton<IMessageBoxService, DXMessageBoxService>();
      
    2. Specify the corresponding ViewModel property:

      public class MainViewModel {
          readonly IMessageBoxService messageBoxService;
          public MainViewModel(IMessageBoxService messageBoxService) {
              this.messageBoxService = messageBoxService;
          }
      }
      

    Tip

    If you configure the service to work with an individual View, dependency injection is not recommended. Use the technique described in the following section instead: Implement Services in Your Application.