2

我花了两周时间搜索google,bing,堆栈溢出和msdn文档,试图找出如何为我的移动应用程序执行适当的依赖注入发展。要清楚,我每天都会在网络应用程序中做DI。我不需要关于什么,谁,以及为什么DI很重要的速成课程。我知道它是,并且总是拥抱它。UWP模板10和服务异常注入(MVVM)不是WPF

我需要了解的是,这是如何在移动应用程序领域发挥作用的,特别是UWP Template 10 Mobile应用程序。我可以在“.net/Asp应用程序中”RegisterType(new XYZ).Singleton()blah“{please forgive syntax;只是一个例子}在App_Start.ConfigureServices中。这在.netcore中几乎完全相同,并且赋予了一些语法上的改变。

我的问题是现在我试图提供我的API是要去UWP应用程序,需要消化我的IXYZ服务。我绝不认为他们应该每次都“新”一个实例。必须有一种方法将它注入UWP方的容器中;我觉得我很缺少很简单的过程。

这里是我的代码:

App.xaml.cs

public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args) 
    { 
     // TODO: add your long-running task here 

     //if (args.Kind == ActivationKind.LockScreen) 
     //{ 

     //} 
     RegisterServices(); 
     await NavigationService.NavigateAsync(typeof(Views.SearchCompanyPage)); 

    } 

public static IServiceProvider Container { get; private set; } 

private static void RegisterServices() 
{ 
    var services = new ServiceCollection(); 
    services.AddSingleton<IXYZ, XYZ>(); 
    Container = services.BuildServiceProvider(); 
} 

MainPage.xaml.cs中:

public MainPage() 
{ 
    InitializeComponent(); 
    NavigationCacheMode = NavigationCacheMode.Enabled; 
} 

MainPageViewModel:

public class MainPageViewModel : ViewModelBase 
{ 
    private readonly IXYZ _xyz; 
    public MainPageViewModel(IXYZ xyz) 
    { 
     //Stuff 
     _xyz= xyz; 
    } 

} 

我现在得到错误: XAML MainPage ... ViewModel类型无法构建。为了在XAML中构建,类型不能是抽象的,接口嵌套的泛型或结构,并且必须具有公共的默认构造函数。

我愿意使用任何品牌的IoC容器,但我需要的是如何在UWP应用程序中正确使用DI服务的示例。关于DI的99.9%的问题是关于Views(即Prism?)而不仅仅是一个服务的简单DI(即DataRepo;又名API/DataService)。

再次,我觉得我错过了一些明显的东西,需要在正确的方向轻推。有人可以向我展示一个示例项目,基本代码或基础鞭挞我如何不应该成为程序员...请不要这样做(我不知道我的自我是否可以接受它)。

+0

如果你能同时有发生,这将极大地改善DI – mvermef

+0

大规模的重构有一个实现,但它不是你通常会使用已经在目前的版本上的NuGet – mvermef

+0

HTTPS烤什么://计算器。 com/questions/38023604/dependency-injection-using-template-10 – mvermef

回答

0

在@mvermef的帮助和SO问题Dependency Injection using Template 10我找到了解决方案。原来这是一个兔子洞,我遇到了问题。

第一个问题是让依赖注入工作。一旦我能够从上述源代码中弄清楚,我就能够开始将我的服务注入ViewModels,并将它们设置到后台代码中的DataContext中。

然后我遇到了一个注入问题,注入我的IXYZ服务到UserControls的ViewModels。

页面和它们的ViewModels工作得很好,但是我的UserControl的DataContext没有被UserControl的ViewModel注入。他们被页面的ViewModel注入。

最终的解决方案竟然是确保该用户控件曾在DataContext正在XAML设置没有后面的代码,因为我们与网页一样,然后在创建一个DependencyProperty后面的代码。

显示下面的基本解决方案。

为了使它工作,我开始:

APP.XAML.CS

public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args) 
{ 
     // long-running startup tasks go here 
     RegisterServices(); 
     await Task.CompletedTask; 
} 

private static void RegisterServices() 
{ 
     var services = new ServiceCollection(); 
     services.AddSingleton<IRepository, Repository>(); 
     services.AddSingleton<IBinderService, BinderServices>(); 

     **//ViewModels** 
     **////User Controls** 
     services.AddSingleton<AddressesControlViewModel, AddressesControlViewModel>(); 
     services.AddSingleton<CompanyControlViewModel, CompanyControlViewModel>(); 

     **//ViewModels** 
     **////Pages** 
     services.AddSingleton<CallListPageViewModel, CallListPageViewModel>(); 
     services.AddSingleton<CallListResultPageViewModel, CallListResultPageViewModel>(); 
     etc.... 

     Container = services.BuildServiceProvider(); 
} 

public override INavigable ResolveForPage(Page page, NavigationService navigationService) 
{ 
     **//INJECT THE VIEWMODEL FOR EACH PAGE** 
     **//ONLY THE PAGE NOT USERCONTROL** 
     if (page is CallListPage) 
     { 
      return Container.GetService<CallListPageViewModel>(); 
     } 
     if (page is CallListResultPage) 
     { 
      return Container.GetService<CallListResultPageViewModel>(); 
     } 

     etc... 
     return base.ResolveForPage(page, navigationService); 
    } 

在后面的代码的页面

CALLLISTPAGE.XAML.CS

public CallListPage() 
    { 
     InitializeComponent(); 
    } 

    CallListPageViewModel _viewModel; 

    public CallListPageViewModel ViewModel 
    { 
     get { return _viewModel ?? (_viewModel = (CallListPageViewModel)DataContext); } 
    } 

在XAML中添加用户控件

CALLLISTPAGE.XAML

<binder:CompanyControl Company="{x:Bind ViewModel.SelectedCompany, Mode=TwoWay}"/>

在你的用户控件确保到DataContext添加到XAML 后面就像我们做了与页面的代码。

COMPANYCONTROL.XAML

<UserControl.DataContext> 
    <viewModels:CompanyControlViewModel x:Name="ViewModel" /> 
</UserControl.DataContext> 

在用户控件的代码后面加一个依赖属性

COMPANYCONTROL.XAML.CS

public static readonly DependencyProperty CompanyProperty = DependencyProperty.Register(
     "Company", typeof(Company), typeof(CompanyControl), new PropertyMetadata(default(Company), SetCompany)); 

    public CompanyControl() 
    { 
     InitializeComponent(); 
    } 

    public Company Company 
    { 
     get => (Company) GetValue(CompanyProperty); 
     set => SetValue(CompanyProperty, value); 
    } 

    private static void SetCompany(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var control = d as CompanyControl; 
     var viewModel = control?.ViewModel; 
     if (viewModel != null) 
      viewModel.Company = (Company) e.NewValue; 
    } 

到底我不知道如果这是一个优雅的解决方案,但它的作品。