2016-05-26 34 views
7

我有一個基於Template10的應用程序,並希望使用IoC處理依賴注入。我傾向於使用Unity來做到這一點。我的應用程序分爲三個組件:如何在Template10中使用Unity IoC容器?

  1. UI(通用應用)
  2. UI邏輯(通用庫)
  3. 核心邏輯(便攜式庫)。

我有以下問題:

  1. 我應該使用一個容器爲整個應用程序,或創建一個爲每個組件?
  2. 我應該在哪裏創建容器並註冊我的服務?
  3. 各個程序集中的不同類應該如何訪問容器?單身模式?

我已閱讀了很多關於DI和IoC的知識,但我需要知道如何在實踐中應用所有理論,特別是在Template10中。

代碼註冊:

// where should I put this code? 
var container = new UnityContainer(); 
container.RegisterType<ISettingsService, RoamingSettingsService); 

然後代碼檢索實例:

var container = ??? 
var settings = container.Resolve<ISettingsService>(); 
+0

[IOC/DI的可能的複製 - 爲什麼我要引用的所有圖層/入門組件應用程序?](http://stackoverflow.com/questions/9501604/ioc-di-why-do-i-have-to-reference-all-layers-assemblies-in-entry-application) – NightOwl888

回答

3

我不熟悉的Unity Container

我的例子是使用LightInject,你可以應用類似的概念,使用Unity。 要在ViewModel上啓用DI,您需要覆蓋項目上App.xaml.csResolveForPage

public class MainPageViewModel : ViewModelBase 
{ 
    ISettingsService _setting; 
    public MainPageViewModel(ISettingsService setting) 
    { 
     _setting = setting; 
    } 
} 


[Bindable] 
sealed partial class App : Template10.Common.BootStrapper 
{ 
    internal static ServiceContainer Container; 

    public App() 
    { 
     InitializeComponent(); 
    } 

    public override async Task OnInitializeAsync(IActivatedEventArgs args) 
    { 
     if(Container == null) 
      Container = new ServiceContainer(); 

     Container.Register<INavigable, MainPageViewModel>(typeof(MainPage).FullName); 
     Container.Register<ISettingsService, RoamingSettingsService>(); 

     // other initialization code here 

     await Task.CompletedTask; 
    } 

    public override INavigable ResolveForPage(Page page, NavigationService navigationService) 
    { 
     return Container.GetInstance<INavigable>(page.GetType().FullName); 
    } 
} 

Template10機器會自動設置DataContextMainPageViewModel,如果你想使用{x:bind}MainPage.xaml.cs

public class MainPage : Page 
{ 
    MainPageViewModel _viewModel; 

    public MainPageViewModel ViewModel 
    { 
     get { return _viewModel??(_viewModel = (MainPageViewModel)this.DataContext); } 
    } 
} 
+0

感謝您的答案!這對我很好!有沒有辦法將VM注入Shell視圖? –

+0

@NickGoloborodko我不太瞭解你的問題,也許你應該創建新的SO問題呢? –

0

這裏是一個小例子,我如何使用統一模板和10

1 。創建一個ViewModel

我還創建了一個DataService類來創建一個人員列表。 查看[Dependency]註釋。

public class UnityViewModel : ViewModelBase 
{ 
    public string HelloMessage { get; } 

    [Dependency] 
    public IDataService DataService { get; set; } 

    private IEnumerable<Person> people; 
    public IEnumerable<Person> People 
    { 
     get { return people; } 
     set { this.Set(ref people, value); } 
    } 

    public UnityViewModel() 
    { 
     HelloMessage = "Hello !"; 
    } 

    public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, 
     IDictionary<string, object> suspensionState) 
    { 
     await Task.CompletedTask; 
     People = DataService.GetPeople(); 
    } 
} 

2.創建一個類來創建並填寫您的UnityContainer

添加UnityViewModel和DataService在給unityContainer。 創建屬性以解析UnityViewModel。

public class UnitiyLocator 
{ 
    private static readonly UnityContainer unityContainer; 

    static UnitiyLocator() 
    { 
     unityContainer = new UnityContainer(); 
     unityContainer.RegisterType<UnityViewModel>(); 
     unityContainer.RegisterType<IDataService, RuntimeDataService>(); 
    } 

    public UnityViewModel UnityViewModel => unityContainer.Resolve<UnityViewModel>(); 
} 

3.將UnityLocator添加到您的應用程序。XAML

<common:BootStrapper x:Class="Template10UWP.App" 
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:common="using:Template10.Common" 
       xmlns:mvvmLightIoc="using:Template10UWP.Examples.MvvmLightIoc" 
       xmlns:unity="using:Template10UWP.Examples.Unity"> 


<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="Styles\Custom.xaml" /> 
      <ResourceDictionary> 
       <unity:UnitiyLocator x:Key="UnityLocator" /> 
      </ResourceDictionary> 
     </ResourceDictionary.MergedDictionaries> 

     <!-- custom resources go here --> 

    </ResourceDictionary> 
</Application.Resources> 

4.創建頁面

使用UnityLocator設置UnityViewModel爲的DataContext並綁定屬性的控件

<Page 
x:Class="Template10UWP.Examples.Unity.UnityMainPage" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="using:Template10UWP.Examples.Unity" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
DataContext="{Binding Source={StaticResource UnityLocator}, Path=UnityViewModel}" 
mc:Ignorable="d"> 

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 
    <TextBlock Text="{Binding HelloMessage}" HorizontalAlignment="Center" 
       VerticalAlignment="Center" /> 

    <ListBox Grid.Row="1" ItemsSource="{Binding People}" DisplayMemberPath="FullName"> 

    </ListBox> 
</Grid> 

當頁面解析UnityViewModel時,DataService將自動注入。

我們您的問題

  1. 這取決於項目如何互相依賴。我不確定什麼是最好的解決方案,但我想我會嘗試使用一個UnityContainer並將其放置在覈心庫中。

  2. 我希望我的例子回答了這個問題

  3. 我希望我的例子回答了這個問題