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

到底我不知道如果這是一個優雅的解決方案,但它的作品。