IoC - разрешить окна WPF с параметрами введенного объекта - PullRequest
2 голосов
/ 04 июля 2019

Моя первая попытка использования контейнера IoC. Программа имеет несколько окон различного типа, которые обычно открываются через меню в MainWindow. Тем не менее, в принципе это может быть и дальше по цепочке. Эти окна обычно требуют внедрения одного или нескольких синглтон-классов, назовем их здесь IManager1/2/3. Итак, мне нужно всплыть эти IManagers до MainWindow, или я могу разрешить каждое окно в корне (здесь в App class)?

В любом случае, как это будет сделано?

Мне не нужно использовать DryIoc, но это именно то, что я выбрал для тестирования.

   public partial class App : Application
{
    DryIoc.Container container = new DryIoc.Container();

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        RegisterIoc();

        var mainwindow = new MainWindow(); 
        mainwindow.Show();
    }

    public void RegisterIoc()
    {
        container.Register<IManager1, Manager1>(Reuse.Singleton);
        container.Register<IManager2, Manager2>(Reuse.Singleton);
        container.Register<IManager3, Manager3>(Reuse.Singleton);
    }
}

public MainWindow()
{
    public MainWindow()
    {
    }

    void OpenNewWindow2()
    {
        var w = new Window2(?, ?, ?);
        w.Show();
    }
}

public class Window2
{
    IManager1 man1;
    IManager2 man2;
    IManager3 man3;

    public Window2(IManager1 man1, IManager2 man2, IManager3 man3)
    {
        this.man1 = man1;
        this.man2 = man3;
        this.man3 = man3;
    }
}

1 Ответ

2 голосов
/ 05 июля 2019

Рассмотрим следующий принцип явной зависимости и сделав Window2 зависимостью MainWindow

Например

public class MainWindow {
    private readonly Func<Window2> window2;

    public MainWindow(Func<Window2> window2) {
        this.window2 = window2;
    }

    public void OpenNewWindow2() {
        var window = window2(); // invoke factory delegate
        window.Show();
    }
}

Выше показано использование Func<T> в качестве делегата фабрикикоторый будет действовать как оболочка для отложенного разрешения требуемой зависимости.Каждый раз, когда фабричный делегат вызывается, он разрешает новый экземпляр Window2, инвертируя элемент управления MainWindow, который должен инициализировать его вручную;

App.Application_Startup используется как корень композиции, где вы бызарегистрируйте каждую вещь в контейнере и разрешите MainWindow, ваш корневой объект

public partial class App : Application {
    DryIoc.Container container;

    private void Application_Startup(object sender, StartupEventArgs e) {
        container = RegisterIoc();    
        var mainwindow = container.Resolve<MainWindow>(); 
        mainwindow.Show();
    }

    private DryIoc.Container RegisterIoc() {
        var container = new DryIoc.Container();
        container.Register<MainWindow>();
        container.Register<Window2>();
        container.Register<IManager1, Manager1>(Reuse.Singleton);
        container.Register<IManager2, Manager2>(Reuse.Singleton);
        container.Register<IManager3, Manager3>(Reuse.Singleton);
        return container;
    }
}

Обратите внимание, что для разрешения окон необходимо также убедиться, что они также зарегистрированы в контейнере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...