如何在Template10中使用Unity IoC容器?

我有一个基于Template10的应用程序,并希望使用IoC来处理依赖注入。 我倾向于使用Unity来做到这一点。 我的应用程序分为三个程序集:

  • UI(通用应用程序)
  • UI逻辑(通用库)
  • 核心逻辑(便携式图书馆)。
  • 我有这些问题:

  • 我应该为整个应用程序使用单个容器还是为每个程序集创建一个容器?
  • 我应该在哪里创建容器并注册我的服务?
  • 各个组件中的不同类应该如何访问容器? 单身模式?
  • 我已阅读了很多关于DI和IoC的知识,但我需要知道如何在实践中应用所有理论,特别是在Template10中。

    代码注册:

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

    然后检索实例的代码:

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

    我不熟悉Unity Container

    我的例子是使用LightInject ,你可以使用Unity来应用类似的概念。 要在ViewModel上启用DI,您需要在您的项目上覆盖App.xaml.cs上的ResolveForPage

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

    这里是我如何使用Unity和Template 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添加到您的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="StylesCustom.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>
    

    DataService将在页面解析UnityViewModel时自动注入。

    现在你的问题

  • 这取决于项目如何相互依赖。 我不确定什么是最好的解决方案,但我想我会尝试使用一个UnityContainer并将其放置在核心库中。

  • 我希望我的例子能够回答这个问题

  • 我希望我的例子能够回答这个问题

  • 链接地址: http://www.djcxy.com/p/34241.html

    上一篇: How do I use a Unity IoC container with Template10?

    下一篇: Is JavaScript location.href call is asynchronous?