Microsoft 純正 Dependency Injection ライブラリ試してみた
V-VM を Dependency Injection でつなげる例
using System; using System.Windows; using MessagePipe; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.DependencyInjection; namespace MessagePipeTest2 { public partial class App : Application { IHost host; private void Application_Startup(object sender, StartupEventArgs e) { host = CreateHostBuilder().Build(); var vm = host.Services.GetRequiredService<MainWindowVM>(); var w = new MainWindow(); w.DataContext = vm; w.Closed += (sender, e) => host.Dispose(); w.Show(); host.RunAsync(); } static IHostBuilder CreateHostBuilder() { return Host.CreateDefaultBuilder() .ConfigureServices((ctx, services) => { services.AddMessagePipe(); services.AddHostedService<Worker>(); services.AddSingleton<MainWindowVM>(); }); } } }
AddSingleton で VM をサービスに登録。必要なタイミングで GetRequiredService でインスタンス化して V の DataContext に設定。
M の部分は AddHostedService でサービスに登録すると同時にインスタンス化している。
VM - M 感は MessagePipe の Pub-Sub で繋げてやり取りする。
↓↓↓↓↓↓↓ VM
using System; using MessagePipe; using Prism.Mvvm; namespace MessagePipeTest2 { class MainWindowVM : BindableBase { private int _value; public int Value { get { return _value; } set { SetProperty(ref _value, value); } } private string _text; public string Text { get { return _text; } set { SetProperty(ref _text, value); } } ISubscriber<MyEvent> subscriber; readonly IDisposable disposable; public MainWindowVM(ISubscriber<MyEvent> subscriber) { this.subscriber = subscriber; var bag = DisposableBag.CreateBuilder(); this.subscriber.Subscribe(Callback).AddTo(bag); disposable = bag.Build(); } public void Callback(MyEvent e) { Value = e.Value; Text = e.Text; } void Close() { disposable.Dispose(); } } }
↓↓↓↓↓↓↓↓ M
using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using MessagePipe; namespace MessagePipeTest2 { class Worker : BackgroundService { IPublisher<MyEvent> publisher; MyEvent e; public Worker(IPublisher<MyEvent> publisher) { this.publisher = publisher; e = new MyEvent(); } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Run(() => { while (!stoppingToken.IsCancellationRequested) { e.Value++; e.Text += DateTime.Now.ToString() + "\n"; publisher.Publish(e); } }); } } }