DrollDread
DrollDread

Reputation: 371

WPF - Passing dependencies between windows

I have Login window and a Home window, inside the login class the Home is opened and the Login is closed:

Home home = new Home(user, _gitApiService);
home.Show();
Close();

Because the Home class relies on a dependency of IGitApiService, I am passing the dependency via the window class's constructor:

public partial class Home : Window
{
    private readonly IGitApiService _gitApiService;

    public Home(User user, IGitApiService gitApiService)
    {
         _gitApiService = gitApiService;

...etc

This seems like bad practice to me, is there any cleaner way of accessing/instaniating the IGitApiService?

(For context the GitApiService is just a class with api calls using HttpClient)

Upvotes: 1

Views: 887

Answers (2)

Nkosi
Nkosi

Reputation: 247088

Slight design change to Home window

public partial class Home : Window {
    private readonly IGitApiService _gitApiService;

    public Home(IGitApiService gitApiService) {
         _gitApiService = gitApiService;
    }

    public User User { get; set; }

    //...
}

I would have a window service responsible for showing a desired window

public interface IWindowService {
    public void Show<TWindow>(Action<TWindow> configure = null) where TWindow : Window;
}

public class WindowService : IWindowService {
    private readonly IServiceProvider services;

    public WindowService(IServiceProvider services) {
        this.services = services
    }

    public void Show<TWindow>(Action<TWindow> configure = null) where TWindow : Window {
        var window = services.GetService<TWindow>();
        if(configure != null) {
            configure(window);
        }

        window.Show();
    }
}

With that in place you inject your window service and use it like

windowSevie.Show<Home>(window => window.User = user);
Close();

Any explicit dependencies are injected when the window is resolved, and the configure delegate allows flexibility to populate any other members as needed

Upvotes: 1

Eugene Podskal
Eugene Podskal

Reputation: 10401

Assuming that there are only a few dependencies then such poor man's/pure DI isn't something really bad.

But if it is a common scenario and there are many dependencies, then by all means register a factory for the Home page (as user seems to be some domain object that can't be registered in CompositionRoot):

 services.Register<Func<User, Home>>(context => 
     user => new Home(user, context.Resolve<IGitApiService>());

or however explicitly or implicitly it is done in the DI framework used in the application.

Upvotes: 3

Related Questions