How to use Unity IoC container with Template10?

I have an application based on Template10 and I want to handle dependency injection using IoC. I tend to use Oneness for this. My application is divided into three assemblies:

  • UI (universal application)
  • User Interface Logic (Universal Library)
  • Core logic (portable library).

I have the following questions:

  • Should I use one container for the entire application or create one for each assembly?
  • Where should I create a container and register my services?
  • How do different classes in different assemblies access the container (s)? Singleton Template?

I read a lot about DI and IoC, but I need to know how to put the whole theory into practice, especially in Template10.

Registration code:

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

And then the code to retrieve the instances:

 var container = ??? var settings = container.Resolve<ISettingsService>(); 
+7
c # uwp unity-container template10
source share
2 answers

I am not familiar with Unity Container .

My example uses LightInject , you can apply a similar concept using Unity . To enable DI on ViewModel , you need to override ResolveForPage on App.xaml.cs in your project.

 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 will automatically set the DataContext to MainPageViewModel if you want to use {x:bind} on MainPage.xaml.cs :

 public class MainPage : Page { MainPageViewModel _viewModel; public MainPageViewModel ViewModel { get { return _viewModel??(_viewModel = (MainPageViewModel)this.DataContext); } } } 
+3
source share

here is a small example of how I use Unity and Template 10.

1. Create a ViewModel

I also created a DataService class to create a list of people. Take a look at the [Dependency] annotation.

 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. Create a class to create and populate your UnityContainer

Add UnityViewModel and DataService to unitContainer. Create a property to enable 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. Add UnityLocator to your app.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. Create page

Use UnityLocator to set UnityViewModel as DataContext and bind properties to controls

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

The DataService will be automatically entered when the page allows the UnityViewModel.

Now for your questions

  • It depends on how the projects depend on each other. I'm not sure if this is the best solution, but I think I will try to use one UnityContainer and put it in the main library.

  • I hope my examples answered this question

  • I hope my examples answered this question

0
source share

All Articles