Technology sharing

WPF/C#: Quomodo dependentiae deducendi iniectio in WPF

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Praefatio

Hic articulus utitur WPF Gallery ad iniectionem conceptus notiones dependentiae discendi injectiones et quomodo dependentiam iniectio in WPF praestare.

Quid est dependentia iniectio

Dependentia Iniectio (DI) est forma designativa adhibita ad inversionem imperii (IoC) principium. Praecipuum propositum dependentiae iniectio est ad creationem obiectorum et administrationem dependentiarum inter obiecta ab intra obiecto transferendi ad vas externum seu compagem, eoque meliori codicis conservabilitatem, testabilitatis et flexibilitatem.

Core conceptio dependentiae iniectio

  1. rely : Res aliud requirit ut opus suum perficiat, illud ab hoc dependet. Exempli gratia, classis OrderService nititur in classe producta repositoria ad informationem productam obtinendam.
  2. iniectio : Transeamus objectum dependens ad id quod indiget obiecto, pro dimisso objecto quod indiget, ipsum objectum dependens creare. Iniectio per constructores, proprietates seu methodos parametri perfici potest.
  3. continens : compage seu bibliotheca quae objectum creationis et clientelas administrat. Continens est responsabilis obiectis instantiantibus, dependentiis resolventibus, objecta dependentia injiciendo in objecta quae illis requirunt.

Genera dependentiae iniectio

conditor iniectio: The dependent object per fabricatorem classis transivit.

public class OrderService
{
    private readonly IProductRepository _productRepository;

    public OrderService(IProductRepository productRepository)
    {
        _productRepository = productRepository;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Res iniectio: Dependentes res publicas classium proprietates trajiciunt.

public class OrderService
{
    public IProductRepository ProductRepository { get; set; }
}
  • 1
  • 2
  • 3
  • 4

modum iniectio: Dependens objectum per modum parametri classis.

public class OrderService
{
    public void ProcessOrder(IProductRepository productRepository)
    {
        // 使用 productRepository 处理订单
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Quare dependentia iniectio est necessaria

Dependentia Iniectio (DI) est forma designativa per quam creatio obiectorum et administratio clientium inter obiecta transferri possunt ab obiecto ad externum continens seu compagem. Plures rationes et commoda dependentiae iniectio momenti sunt;

  1. Reduce coitu Dependentia iniectio transfert administrationem clientum ab intra objectum ad externum continens, ita ut objectum scire non opus sit quomodo creare objecta dependet, sed solum scire interfaciem objecti dependens. Hoc signanter potest minuere copulam inter res et codicem magis modulari et flexibilem efficere.
  2. Meliorem testability : Dependentia iniectio unitatis probatio facilior et efficacior facit. Utendo obiectis ludibriis vel stipulis pro obiectis actualibus dependentibus, tincidunt facere possunt unitatem probationis sine actuali exsecutione freti. Hoc adiuvat libertatem ac fidem test.
  3. Improve maintainability : Cum dependentia iniectio copulationem redigit ad objecta, signum fit modulatio magis et evidens. Quo facilius codicem intelligat et teneat. Cum obiectum dependens mutare vel subrogare debes, tantum debes mutare configurationem aut adnotationem informationem, sine modificatione codicem qui obiecto utitur.
  4. Amplio flexibilitate : Dependentia iniectio systema flexibiliorem facit ac facile substituere potest obiecta dependentia ad varias functiones vel mores consequendos. Exempli gratia, accessus diversorum database stratorum implementations per limas conformationes vel codicem commutari potest sine modificatione negotii logicae.
  5. Promovere de separatione : Dependentia iniectio adiuvat ad curarum separationem (Separatio curarum), ut unumquodque objectum solum in suis officiis intendere debeat, sine cura quomodo res ab illis dependet ad creandum et obtinendum. Hoc adiuvat ad meliorem codicem perspicuitatem et conservabilitatem.
  6. Firmamentum consiliorum et optimorum operum : Dependentia iniectio est fundamentum multorum consiliorum exemplaria ac praxis optimarum, ut Inversio Control (IoC), Service Locator Pattern, etc. Utendo dependentiae injectione, tincidunt facilius haec exemplaria et consuetudines efficere possunt, eo quod qualitatem et scalability codicem augent.

Quomodo ad dependentiam deducendi iniectio

Hic articulus utitur WPF Gallery project ad discendum quomodo dependentia iniectio in WPF utatur.

https://github.com/microsoft/WPF-Samples/blob/main/SampleApplications/WPFGallery

Ad dependentiam iniectio in hoc incepto deducendi, hae duae fasciculi adhibentur:

image-2024071110435001

Primum vide contenta App.xaml.cs:

public partial class App : Application
{

    private static readonly IHost _host = Host.CreateDefaultBuilder()
        .ConfigureServices((context, services) =>
        {
            services.AddSingleton<INavigationService, NavigationService>();
            services.AddSingleton<MainWindow>();
            services.AddSingleton<MainWindowViewModel>();
            
            services.AddTransient<DashboardPage>();
            services.AddTransient<DashboardPageViewModel>();

            services.AddTransient<ButtonPage>();
            services.AddTransient<ButtonPageViewModel>();
            services.AddTransient<CheckBoxPage>();
            services.AddTransient<CheckBoxPageViewModel>();
            services.AddTransient<ComboBoxPage>();
            services.AddTransient<ComboBoxPageViewModel>();
            services.AddTransient<RadioButtonPage>();
            services.AddTransient<RadioButtonPageViewModel>();
            services.AddTransient<SliderPage>();
            services.AddTransient<SliderPageViewModel>();
            services.AddTransient<CalendarPage>();
            services.AddTransient<CalendarPageViewModel>();
            services.AddTransient<DatePickerPage>();
            services.AddTransient<DatePickerPageViewModel>();
            services.AddTransient<TabControlPage>();
            services.AddTransient<TabControlPageViewModel>();
            services.AddTransient<ProgressBarPage>();
            services.AddTransient<ProgressBarPageViewModel>();
            services.AddTransient<MenuPage>();
            services.AddTransient<MenuPageViewModel>();
            services.AddTransient<ToolTipPage>();
            services.AddTransient<ToolTipPageViewModel>();
            services.AddTransient<CanvasPage>();
            services.AddTransient<CanvasPageViewModel>();
            services.AddTransient<ExpanderPage>();
            services.AddTransient<ExpanderPageViewModel>();
            services.AddTransient<ImagePage>();
            services.AddTransient<ImagePageViewModel>();
            services.AddTransient<DataGridPage>();
            services.AddTransient<DataGridPageViewModel>();
            services.AddTransient<ListBoxPage>();
            services.AddTransient<ListBoxPageViewModel>();
            services.AddTransient<ListViewPage>();
            services.AddTransient<ListViewPageViewModel>();
            services.AddTransient<TreeViewPage>();
            services.AddTransient<TreeViewPageViewModel>();
            services.AddTransient<LabelPage>();
            services.AddTransient<LabelPageViewModel>();
            services.AddTransient<TextBoxPage>();
            services.AddTransient<TextBoxPageViewModel>();
            services.AddTransient<TextBlockPage>();
            services.AddTransient<TextBlockPageViewModel>();
            services.AddTransient<RichTextEditPage>();
            services.AddTransient<RichTextEditPageViewModel>();
            services.AddTransient<PasswordBoxPage>();
            services.AddTransient<PasswordBoxPageViewModel>();
            services.AddTransient<ColorsPage>();
            services.AddTransient<ColorsPageViewModel>();

            services.AddTransient<LayoutPage>();
            services.AddTransient<LayoutPageViewModel>();
            services.AddTransient<AllSamplesPage>();
            services.AddTransient<AllSamplesPageViewModel>();
            services.AddTransient<BasicInputPage>();
            services.AddTransient<BasicInputPageViewModel>();
            services.AddTransient<CollectionsPage>();
            services.AddTransient<CollectionsPageViewModel>();
            services.AddTransient<MediaPage>();
            services.AddTransient<MediaPageViewModel>();
            services.AddTransient<NavigationPage>();
            services.AddTransient<NavigationPageViewModel>();
            services.AddTransient<TextPage>();
            services.AddTransient<TextPageViewModel>();
            services.AddTransient<DateAndTimePage>();
            services.AddTransient<DateAndTimePageViewModel>();
            services.AddTransient<StatusAndInfoPage>();
            services.AddTransient<StatusAndInfoPageViewModel>();
            services.AddTransient<SamplesPage>();
            services.AddTransient<SamplesPageViewModel>();
            services.AddTransient<DesignGuidancePage>();
            services.AddTransient<DesignGuidancePageViewModel>();

            services.AddTransient<UserDashboardPage>();
            services.AddTransient<UserDashboardPageViewModel>();

            services.AddTransient<TypographyPage>();
            services.AddTransient<TypographyPageViewModel>();

            services.AddSingleton<IconsPage>();
            services.AddSingleton<IconsPageViewModel>();

            services.AddSingleton<SettingsPage>();
            services.AddSingleton<SettingsPageViewModel>();

            services.AddSingleton<AboutPage>();
            services.AddSingleton<AboutPageViewModel>();
        }).Build();


    [STAThread]
    public static void Main()
    {
        _host.Start();

        App app = new();
        app.InitializeComponent();
        app.MainWindow = _host.Services.GetRequiredService<MainWindow>();
        app.MainWindow.Visibility = Visibility.Visible;
        app.Run();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114

image-20240711083011393

Quid est IHost?

In C#,IHost est interface quod in .NET facere et configurare applicationsHostnotio abstracta.IHost Interfacius definit collectionem officiorum et partium quae ad applicationem incipere, currere et administrare. Cum applicationibus Core ASP.NET typice adhibetur, sed etiam cum aliis applicationibus NET genera laborat, ut applicationes consolatoriae vel programmata WPF.

image-20240711082817268

IHostInterface estHostBuilderClassis exsecutio, quae creationem et configurationem praebetIHostmodi instantia.HostBuilderPermittit tibi varia officia addere, sicut logging, configuratione, dependentiam iniectio vasis, etc., et configurare initium ac finem agendi applicationis tuae.

image-20240711083048854

image-20240711083156306

Commodum rationes praebet ad Microsoft.Extensions.Hosting.IHostBuilder instantiae creandi cum defaltis praefiguratis.

image-20240711083713204

IHostBuilder refert an.

image-20240711084145756

image-20240711084211035

continens operas add. Haec operatio potest dici multiplex tempora et effectus eius cumulativus.

Sensus parametri configureDelegati est delegatum Microsoft.Extensions configurare. DependencyInjection.IServiceCollection.
Haec collectio ad fabricam System.IServiceProvider adhibebitur.

Delegatus duas species moduli requirit: HostBuilderContext et IServiceCollection, quae valorem nullum habent.

image-20240711084853971

Expressio Labda quae typo delegato satisfacit huc transigitur.

In C#,() => {} Ia syntaxin est locutionum in Labda. Expressiones Labda sunt leve pondus delegatus fasciculus qui permittit te methodum anonymum definire et eam ut modulum ad methodum quae delegatis vel expressionibus arboribus sustinet.

Labda locutiones brevem methodum ad methodos definiendas praebent, utiles praesertim cum methodos ad alios modos parametri transire debes.

image-20240711085344696

Cum officia additis, duo cycli vitae hic sunt, praeter AddSingleton et AddTransient, additur etiam AddScoped.

Hae modi definiunt vitam cycli muneris, id est, quomodo operae instantiae creantur et in applicatione conficiantur.

AddSingleton

  • vitae cyclumSingleton
  • significatio : Unius exempli gratia opera creatur per totam applicationem vitae currendi. Quotiens autem a continente petieris, eadem instantia reddetur.
  • Lorem scaena: Idonea ad officia stateless, seu facultates per totam applicationem communicatae, ut figurationes, caesores, etc.

AddTransient

  • vitae cyclum: Transiens
  • significatio: Quoties servitium petitur a continente, nova instantia creatur.
  • Lorem scaena: Apta ad officia publica, seu missiones quae requirunt novam instantiam pro unaquaque petitione, ut paginae, exempla speculativa, etc.

AddScoped

  • vitae cyclum: Scoped
  • significatio : In unoquoque ambitu, instantiae servitutis sunt singulares. Scopi saepe coniunguntur cum vita cycli petitionis, exempli gratia in applicationibus interretialibus novus scopus creatus cum unaquaque petitione HTTP.
  • Lorem scaena: Apta pro servitiis quae necessitates communicandi instantiarum intra ambitum rogationis, sicut contextui datorum datorum.

uti haec officia

Praecipuum munus:

image-20240711095100016

Start up_host, pass_host.Services.GetRequiredService<MainWindow>();Adepto MainWindow exempli gratia.

Classis MainWindow exemplum sumens, conditorem MainWindow in MainWindow.xaml.cs spectare:

public MainWindow(MainWindowViewModel viewModel, IServiceProvider serviceProvider, INavigationService navigationService)
{
    _serviceProvider = serviceProvider;
    ViewModel = viewModel;
    DataContext = this;
    InitializeComponent();

    Toggle_TitleButtonVisibility();

    _navigationService = navigationService;
    _navigationService.Navigating += OnNavigating;
    _navigationService.SetFrame(this.RootContentFrame);
    _navigationService.Navigate(typeof(DashboardPage));

    WindowChrome.SetWindowChrome(
        this,
        new WindowChrome
        {
            CaptionHeight = 50,
            CornerRadius = default,
            GlassFrameThickness = new Thickness(-1),
            ResizeBorderThickness = ResizeMode == ResizeMode.NoResize ? default : new Thickness(4),
            UseAeroCaptionButtons = true
        }
    );

    this.StateChanged += MainWindow_StateChanged;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

Sublata materia ad hunc locum talis est:

public MainWindow(MainWindowViewModel viewModel, IServiceProvider serviceProvider, INavigationService navigationService)
{
    _serviceProvider = serviceProvider;
    ViewModel = viewModel; 
    _navigationService = navigationService;  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Animadvertisne tibi iam non opus esse novis istis rebus te?

Si dependentia iniectio non adhibeatur, videre licet hoc:

public MainWindow()
{
    _serviceProvider = new IServiceProvider();
    ViewModel = new MainWindowViewModel(); 
    _navigationService = new INavigationService();  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Summatim

Hic articulus primum notionem dependentiae injectionis introducit, deinde explicatur cur dependentia iniectio opus sit, ac demum dependens injectione in WPF per WPF Gallery project uti discat.

refer ad

1、[WPF-Samples/Sample Applications/WPFGallery ad principale · microsoft/WPF-Samples (github.com)] (https://github.com/microsoft/WPF-Samples/tree/main/Sample Applications/WPFGallery)