【问题标题】:WPF - Passing dependencies between windowsWPF - 在窗口之间传递依赖关系
【发布时间】:2019-08-03 14:32:21
【问题描述】:

我有一个登录窗口和一个主页窗口,在登录类中主页是打开的,登录是关闭的:

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

因为Home类依赖于IGitApiService的依赖,所以我通过window类的构造函数传递依赖:

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

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

...等

这对我来说似乎是不好的做法,有没有更清洁的方式来访问/实例化 IGitApiService?

(对于上下文,GitApiService 只是一个使用 HttpClient 进行 api 调用的类)

【问题讨论】:

  • 您使用的是 DI/IoC 容器吗?登录窗口是否也依赖于 IGitApiService 服务?
  • 登录窗口也依赖于相同的服务。我目前正在我的 App.xaml.cs 文件中的配置服务方法中注册接口,如下所示...services.AddHttpClient<IGitApiService, GitApiService>(...等
  • 配置服务方法还将登录注册为瞬态,即services.AddTransient(typeof(Login));我也在从我的启动方法运行var login = ServiceProvider.GetRequiredService<Login>();。,

标签: c# wpf .net-core


【解决方案1】:

假设只有几个依赖项,那么这样的poor man's/pure DI 并不是什么坏事。

但是如果是常见的场景,有很多依赖,那么一定要为首页注册一个工厂(因为user好像是某个域对象,不能在CompositionRoot中注册):

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

或者无论是显式还是隐式,它都是在应用程序中使用的 DI 框架中完成的。

【讨论】:

    【解决方案2】:

    Home 窗口的设计稍作改动

    public partial class Home : Window {
        private readonly IGitApiService _gitApiService;
    
        public Home(IGitApiService gitApiService) {
             _gitApiService = gitApiService;
        }
    
        public User User { get; set; }
    
        //...
    }
    

    我会有一个窗口服务负责显示所需的窗口

    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();
        }
    }
    

    这样你就可以注入你的窗口服务并像使用它一样使用它

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

    在解析窗口时注入任何显式依赖项,并且配置委托允许根据需要灵活地填充任何其他成员

    【讨论】:

      猜你喜欢
      • 2019-10-12
      • 1970-01-01
      • 1970-01-01
      • 2013-11-05
      • 2016-09-10
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多