uwp with c# and mvvm inversion of control (dependency injection)

StudentOfTheGame 1 Reputation point
2021-01-18T17:39:42.78+00:00

so most of my progamming has been done in java where i used a lot of IoC and DPI by injecting all the necessary depencies to the constructors of the newly created objects from the main method. so i injected all the repositories into the services, then the services into the controllers. in this way i only created one instance of each dependency and injected them wherever they were needed.

in java i do it like this:

public class Main {

    public static void main(String[] args) {

        InterfaceRepository<Booking> bookingInterface = new BookingRepository();
        InterfaceRepository<User> userInterface = new UserRepository();

        InterfaceBookingService interfaceBookingService = new BookingService(bookingInterface, userInterface);
        InterfaceUserService interfaceUserService = new UserService(userInterface);

        BookingController bookingController = new BookingController(interfaceBookingService, interfaceUserService);
        UserController userController = new UserController(interfaceUserService)

    }

}

in uwp i'm completely lost on how to do the same as i did in java. how and where are the viewmodels even instanced and how can i inject the repositories into the viewmodels; if some of my repositories are needed by several of the viewmodels, can i inject the same instance of the repositories to the different viewmodels? i want to be able to test my viewmodels, so i want to have the possibility to be flexible with what i inject as well

i'm sorry i don't have any code, this is because i can't even get started coding in uwp with c# and mvvm without finding out how to be able to do IoC and follow the S.O.L.I.D. principles

Universal Windows Platform (UWP)
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,351 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Yan Gu - MSFT 2,676 Reputation points
    2021-01-19T09:40:54.903+00:00

    Hello,

    Welcome to Microsoft Q&A.

    About MVVM in UWP, you could refer to the document. There are samples in the document you could view that where the viewmodles are instanced.

    You could use Microsoft.Extensions.DependencyInjection NuGet package to do the dependency injection.

    Please check the following steps:
    1.Create the MVVM architecture in a C# UWP project.
    2.Click Tools in menu, select the option NuGet Package Manager > Manage NuGet Package for Solution… > Browse, enter Microsoft.Extensions.DependencyInjection in search box, install the package for your project.
    3.Create Container object which maintains all of the dependencies that can be resolved anywhere in the application.

    //App.xaml.cs  
    public App()  
    {  
        this.InitializeComponent();  
        this.Suspending += OnSuspending;  
        Container = ConfigureDependencyInjection();  
    }  
    public IServiceProvider Container { get; }  
    
    IServiceProvider ConfigureDependencyInjection()  
    {  
        var serviceCollection = new ServiceCollection();  
    
        serviceCollection.AddTransient<IMessageService, MessageService>();  
    
        return serviceCollection.BuildServiceProvider();  
    }  
    

    4.Create the MessageService class and the IMessageService interface.

    //Add a new class to create the interface and class  
    public interface IMessageService  
    {  
        string GetMessage();  
    }  
    public class MessageService : IMessageService  
    {  
        public string GetMessage()  
        {  
            return "Hello from Message Service & Dependency Injection";  
        }  
    }  
    

    5.Register MessageService to Container(referring to the code in step 3).
    6.Inject MessageService into your viewmodel class such as MainViewModel class.

    public class MainViewModel  
    {  
        protected IMessageService MessageService { get; }  
        public string Message { get => MessageService.GetMessage(); }  
        public MainViewModel(IMessageService messageService)  
        {  
            MessageService = messageService;  
            ……  
        }  
        ……  
    }  
    

    7.Resolve the MainViewModel, and inject the dependencies by using ActivatorUtilities function to inject parameters into the constructor.

    //MainPage.xaml.cs  
    public MainPage()  
    {  
        this.InitializeComponent();  
        var container = ((App)App.Current).Container;  
        DataContext = ActivatorUtilities.GetServiceOrCreateInstance(container, typeof(MainViewModel));  
    }  
    

    8.Show the message in page.

    //MainPage.xaml  
    <Grid>  
        <TextBlock Text="{Binding Message}" Margin="10" FontSize="20"/>  
    </Grid>  
    

    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    2 people found this answer helpful.
    0 comments No comments

  2. Ivanich 306 Reputation points
    2021-01-19T15:46:36.317+00:00

    There are multiple DI and IoC libraries for UWP, WPF and other XAML frameworks. In addition to Microsoft.Extensions.DependencyInjection mentioned by YanGu-MSFT , you may try Unity - the oldest and one of the most popular libraries working for all frameworks:

    http://unitycontainer.org/
    https://github.com/unitycontainer
    https://www.nuget.org/packages/Unity.Container/

    With Unity you create container, register your types and set [Dependency] attribute on the properties or just pass parameters of registered types in the constructor:

    https://learn.microsoft.com/en-us/previous-versions/msp-n-p/ff660903(v=pandp.20)

    For ViewModels, some people try to invent own tricks and instantiate them in XAML, but usually they are just instantiated in the page's constructor, especially when there are x:Bind bindings in the markup.

    0 comments No comments