unity mvc injection dependency container c# .net unity-container uwp template10

c# - mvc - ninject



¿Cómo uso un contenedor Unity IoC con Template10? (2)

Tengo una aplicación basada en Template10 y quiero manejar mi inyección de dependencia usando IoC. Me inclino por utilizar Unity para esto. Mi aplicación está dividida en tres ensamblajes:

  1. UI (aplicación universal)
  2. UI Logic (Biblioteca universal)
  3. Core Logic (Biblioteca portátil).

Tengo estas preguntas:

  1. ¿Debo usar un solo contenedor para toda la aplicación o crear uno para cada ensamblaje?
  2. ¿Dónde debería crear los contenedores y registrar mis servicios?
  3. ¿Cómo deben acceder las diferentes clases en los diferentes ensambles al contenedor (es)? Patrón Singleton?

He leído mucho sobre DI y IoC, pero necesito saber cómo aplicar toda la teoría en la práctica, específicamente en Template10.

El código para registrarse:

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

Y luego el código para recuperar las instancias:

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


No estoy familiarizado con Unity Container .

Mi ejemplo es usar LightInject , puede aplicar un concepto similar usando Unity . Para habilitar DI en ViewModel , debe anular ResolveForPage en App.xaml.cs en su proyecto.

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 configurará automáticamente DataContext en MainPageViewModel , si desea usar {x:bind} en MainPage.xaml.cs :

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


Aquí hay un pequeño ejemplo de cómo uso la Unidad y la Plantilla 10.

1. Crea un ViewModel

También creé una clase DataService para crear una lista de personas. Eche un vistazo a la anotación [Dependencia].

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. Crea una clase para crear y llenar tu UnityContainer

Agregue UnityViewModel y DataService a unityContainer. Crea una propiedad para resolver el 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. Agregue el UnityLocator a su 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. Crea la página

Utilice UnityLocator para establecer UnityViewModel como DataContext y vincular las propiedades a los controles

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

El DataService se inyectará automáticamente cuando la página resuelva UnityViewModel.

Ahora a tus preguntas

  1. Esto depende de cómo los proyectos dependen el uno del otro. No estoy seguro de cuál es la mejor solución, pero creo que trataría de usar un UnityContainer y colocarlo en la biblioteca central.

  2. Espero que mis ejemplos respondan esta pregunta

  3. Espero que mis ejemplos respondan esta pregunta