UWP] [inyección de dependencia ValueConveter por MarkupExtension

¿Es realmente más ocupado recientemente, pasé algún tiempo considerado el pozo Nuget empacar mi propia microblogging llenar una biblioteca ( https://github.com/h82258652/HN.Social.Weibo Bienvenido a Gangster estrella). dino jefes han tomado el pelo que consigue animados, pero no hacer nada artístico y API composición no está muy familiarizado con, sólo se puede escapar (ja ja ja). Inactivo sin cepillo incidente Github, ver WPF Repo una cuestión de ( https://github.com/dotnet/wpf/issues/499 ), ¿el XAML actual con esta inversión de control casi nada vinculante. Debido al nivel de control requerido constructor sin argumentos, ahora es difícil de lograr. Pero ValueConverter estas cosas, a la siguiente, parece ser que sí, por lo que hacer el siguiente experimento, el éxito y escribió este blog.


El UWP MarkupExtension se introdujo en la versión 16299, por lo que nuestros proyectos tienen que dirigirse a 16299 o más.

patrón general MVVM, por ejemplo, crear ViewModelLocator.cs, aquí contenedor IoC uso el más común Autofac Bueno, citado Autofac.Extras.CommonServiceLocator paquete.

público  de clase ViewModelLocator 
{ 
    estática ViewModelLocator () 
    { 
        var autofacServiceLocator = nueva AutofacServiceLocator (CreateAutofacContainer ()); 
        ServiceLocator.SetLocatorProvider (() => autofacServiceLocator); 
    } 

    Privada  estática IContainer CreateAutofacContainer () 
    { 
        var ContainerBuilder = nueva ContainerBuilder (); 

        // servicios de TODO Registro 

        regresan containerBuilder.Build (); 
    } 
}

Y modificar App.xaml

< Aplicación x: Class = "ConverterIocDemo.App" 
             xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
             xmlns: x = "http://schemas.microsoft.com/winfx/2006 / xaml" 
             xmlns: ViewModels = "usando: ConverterIocDemo.ViewModels" > 
    < Application.Resources > 
        < ResourceDictionary > 
            < ViewModels: ViewModelLocator x: Key = "Locator"  /> 
        </ ResourceDictionary > 
    </ Application.Resources > 
</ Aplicación >


A continuación, añadir un poco de código de prueba él.

de espacio de nombres ConverterIocDemo.Models 
{ 
    público  de clase Persona 
    { 
        pública  cadena Nombre { get ; establecer ; } 

        Pública  int Edad { get ; establecer ; } 
    } 
}
usando ConverterIocDemo.Models; 

de espacio de nombres ConverterIocDemo.Services 
{ 
    público  interfaz IPersonService 
    { 
        cadena GetHello (persona a persona); 
    } 
}
usando System;
usando ConverterIocDemo.Models; 

de espacio de nombres ConverterIocDemo.Services 
{ 
    público  de clase PersonService: IPersonService 
    { 
        pública  cadena GetHello (persona a persona) 
        { 
            si (== persona nula ) 
            { 
                lanzar  nuevos ArgumentNullException (nombredel (persona)); 
            } 

            Var ahora = DateTime.Now;
            si (ahora.hora> = 9 && ahora.hora <= 21 && now.DayOfWeek! = DayOfWeek.Sunday) 
            {
                volver $ " Hola a todos, mi nombre es {person.Name}, {} person.Age años de edad este año " ; 
            } 
            else 
            { 
                retorno  " buena Dafa 996 (de MMP) " ; 
            } 
        } 
    } 
}
usando ConverterIocDemo.Models; 

de espacio de nombres ConverterIocDemo.ViewModels 
{ 
    público  de clase MainViewModel 
    { 
        público MainViewModel () 
        { 
            Persona = nueva persona 
            { 
                Nombre = " justin liu " , 
                Edad = 18 
            }; 
        } 

        Pública Persona Persona { get ; } 
    } 
}
usando ConverterIocDemo.Services;
usando System;
usando Windows.UI.Xaml.Data;
usando ConverterIocDemo.Models; 

de espacio de nombres ConverterIocDemo.Converters 
{ 
    público  de clase PersonSayHelloConverter: IValueConverter 
    { 
        privado  de sólo lectura IPersonService _personService; 

        pública PersonSayHelloConverter (IPersonService PersonService) 
        { 
            _personService = PersonService; 
        } 

        Pública  objeto Convert ( objeto de valor, Tipo targetType, objeto de parámetros,cadena de idioma) 
        { 
            retorno _personService.GetHello ((persona) valor); 
        } 

        Pública  objeto ConvertBack ( objeto de valor, Tipo targetType, objeto parámetro, cadena de idioma) 
        { 
            lanzar  nuevos NotImplementedException (); 
        } 
    } 
}

Modificar ViewModelLocator, este montón de cosas Regístrate.

usando Autofac;
usando Autofac.Extras.CommonServiceLocator;
usando CommonServiceLocator;
usando ConverterIocDemo.Converters;
usando ConverterIocDemo.Services; 

de espacio de nombres ConverterIocDemo.ViewModels 
{ 
    público  de clase ViewModelLocator 
    { 
        estática ViewModelLocator () 
        { 
            var autofacServiceLocator = nueva AutofacServiceLocator (CreateAutofacContainer ()); 
            ServiceLocator.SetLocatorProvider (() => autofacServiceLocator); 
        } 

        pública= MainViewModel principal> ServiceLocator.Current.GetInstance <MainViewModel> (); 

        privada  estática IContainer CreateAutofacContainer () 
        { 
            var ContainerBuilder = nueva ContainerBuilder (); 

            containerBuilder.RegisterType . <PersonService> () Como <IPersonService> (); 
            containerBuilder.RegisterType <MainViewModel> (); 
            containerBuilder.RegisterType <PersonSayHelloConverter> () .SingleInstance (); 

            volver containerBuilder.Build (); 
        } 
    } 
}

Luego está la clave para este artículo, por MarkupExtension este PersonSayHelloConveter el consumidor. Aquí llamé ConverterProviderExtension.

usando CommonServiceLocator;
usando System;
usando Windows.UI.Xaml.Data;
usando Windows.UI.Xaml.Markup; 

de espacio de nombres ConverterIocDemo.Converters 
{ 
    [MarkupExtensionReturnType (Tipo de retorno = typeof (IValueConverter))]
     pública  clase ConverterProviderExtension: MarkupExtension 
    { 
        pública Tipo ConverterType { get ; establecer ; } 

        Protegido  override  objeto ProvideValue () 
        { 
            si (ConverterType == nula ) 
            {
                de banda  nueva nueva ArgumentException El ( " tipo de convertidor no está establecido " ); 
            } 

            retorno ServiceLocator.Current.GetInstance (ConverterType); 
        } 
    } 
}

Luego, busquen en el efecto de la modificación MainPage

< Página x: Class = "ConverterIocDemo.MainPage" 
      xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns: x = "http://schemas.microsoft.com/winfx/2006 / xaml " 
      xmlns: convertidores = "usando: ConverterIocDemo.Converters" 
      xmlns: d = "http://schemas.microsoft.com/expression/blend/2008" 
      xmlns: locales = "usando: ConverterIocDemo" 
      xmlns: mc =" http : //schemas.openxmlformats.org/markup-compatibility/2006" 
      Antecedentes =" {} ThemeResource ApplicationPageBackgroundThemeBrush " 
      DataContext ="{Binding Fuente = {StaticResource Localizador}, Path = Principal} " 
      MC: se ignoran =" d " > 
    < Red > 
        < TextBlock HorizontalAlignment = "centro" 
                   VerticalAlignment = "centro" 
                   texto =" {Binding Path = persona, Converter = {convertidores : ConverterProvider ConverterType = convertidores: PersonSayHelloConverter}} "  /> 
    </ Rejilla > 
</ Página >

En funcionamiento:

Snipaste_2020-04-03_10-31-24

Otra vez en marcha otra vez:

Snipaste_2020-04-03_23-36-27

Está bien.


La teoría puede ser modificado MarkupExtensionReturnTypeAttribute returntype typeof (objeto) ya registrado a continuación, obtener cualquier cosa desde el contenedor IoC que quiere. Pero encontré que parece acabado blog lleno de necesidades seudo. ε = ε = ε = ┏ (゜ ro ゜;) ┛

Supongo que te gusta

Origin www.cnblogs.com/h82258652/p/12625081.html
Recomendado
Clasificación