WPF MVVM, gdzie najlepiej umieścic podstawe kompozycji ?

0

Gdzie w WPF MVVM, najlepiej umieścic podstawe kompozycji? Doszedłem do momentu rozwoju aplikacji gdzie muszę ją uporządkować projektowo, bo coś poprawić albo dodać to teraz koszmar.

W poprzednim projekcie WinForms spinalem cała architekturę ModelViewPresenter w klasie odpowiedzialnej za przełączanie widoków oraz za wstrzykiwanie zależności do prezenterów i widoków i to była klasa uruchamiana w klasie Program. To mi się sprawdziło i było bardzo wygodne. Co prawda KontroleeWidokow miał zależności w każdej warstwie, ale za to całe pozostałe warstwy opierały się faktycznie na abstrakcji, i zupełnie nic nie wiedziały o sobie.

Jak takie coś powtórzyć w WPF MVVM?
Do ViewModeli muszę powstrzykiwac serwisy które z kolei zawierają repozytoria które z kolei mają wstrzykiwane obiekty już konkretnych readerow.
Ponadto pod widoki (UserControl) przełączane w widoku głównym (MainWindow) korzystają z niektórych abstrakcyjnych właściwości MainWindowViewModel i je też chciałbym "wstrzyknąć/przekazać" w takiej podstawie kompozycji do podwidoku.

Ten patent z linku niz j mi nie działa, nie ogarniam jak uruchomić swoją metodę Main zamiast zostawiać ją automatowi.
https://www.jankowskimichal.pl/2011/05/zaginiona-metoda-main/

static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            KontrolerWidokow glownyKontroler = new KontrolerWidokow();

            Application.Run(glownyKontroler.ZwrocOstatnioZaladowanyWidok);
            //Application.Run(new OknoGlowne());
       }
    }

public class KontrolerWidokow : IViewLoader
    {
        private Form ostatnioZaladowanyWidok;

        private IDaneMapowaniaReader readerMapowania;
        private IDanePlanistaReader readerPlanisty;
        private IDaneScalaReader readerScala;
        private IDaneWysylkoweReader readerDanychWysylkowych;

        private ISterownikWidokuGlownego sterownikWidokuGlownego;
        private IWidokOknaGlownego widokOknaGlownego;

        private ISterownikWidokuEtykiet sterownikWidokuEtykiet;
        private IWidokWyboruEtykiety widokWyboruEtykiety;

        private ISterownikWidokuWalidacji sterownikWidokuWalidacji;
        private IWidokWalidacjiWersjiProgramu widokWalidacjiWersjiProgramu;

        public KontrolerWidokow()
        {
            PokazWidokGlowny();
        }

        public void PokazWidokGlowny()
        {
            sterownikWidokuGlownego = new PresenterOknaGlownego(this);

            widokOknaGlownego = new OknoGlowne(sterownikWidokuGlownego);
            sterownikWidokuGlownego.UstawWidok(widokOknaGlownego);            

            OtworzWidok((Form)widokOknaGlownego);
        }

        public void PokazWidokEtykiet()
        {
            sterownikWidokuEtykiet = new PresenterEtykiety(sterownikWidokuGlownego);
            widokWyboruEtykiety = new OknoWyboruEtykiety(sterownikWidokuEtykiet);
            sterownikWidokuEtykiet.UstawWidok(widokWyboruEtykiety);

            OtworzWidok((Form)widokWyboruEtykiety);
        }

        public void PokazWidokWalidacji()
        {

            sterownikWidokuWalidacji = new PresenterWalidacji(sterownikWidokuGlownego);
            widokWalidacjiWersjiProgramu = new OknoWalidacji(sterownikWidokuWalidacji);
            sterownikWidokuWalidacji.UstawWidok(widokWalidacjiWersjiProgramu);

            UstalZrodloDanych_DostepDoBazDanych();
            sterownikWidokuWalidacji.UstawZrodlaDanych(readerScala, readerPlanisty, readerMapowania, readerDanychWysylkowych);

            OtworzWidok((Form)widokWalidacjiWersjiProgramu);
        }

        private void OtworzWidok(Form widok)
        {
            widok.Show();
            ostatnioZaladowanyWidok = widok;
        }

        public Form ZwrocOstatnioZaladowanyWidok
        {
            get { return ostatnioZaladowanyWidok; }
        }

        private void UstalZrodloDanych_DostepDoBazDanych()
        {
            readerMapowania = new MapowanieReader();
            readerPlanisty = new PlanistaReader();
            readerScala = new ScalaReader();
            readerDanychWysylkowych = new ExcelReader();
        }
        private void UstalZrodloDanych_DaneZMockowane()
        {
            //readerMapowania = new MockMapowanieReader();
            //readerPlanisty = new MockPlanistaReader();
            //readerScala = new MockScalaReader();
            //readerDanychWysylkowych = new ExcelReader();
        }
    }
}

2

Nie potrzebujesz metody Main(). Punktem wejścia do aplikacji WPF jest klasa Application, która po kosmetycznej modyfikacji nadaję się na compositom root :

App.xaml

<Application x:Class="WpfApp1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApp1"
            >
    <Application.Resources>
         
    </Application.Resources>
</Application>

App.xaml.cs

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {

        public App()
        {
            Startup += App_Startup;
        }

        private void App_Startup(object sender, StartupEventArgs e)
        {
            // tu se mozemy wstrzykiwać 
            MainWindow = new MainWindow();
            MainWindow.Show();
        }
    }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1