2011-06-07 11 views
5

Estoy usando Prism 4 con extensiones MEF y el patrón MVVM. Durante la inicialización en un módulo que llamo RegisterViewWithRegion (RegionNames.MyRegion, typeof (MyView)), que funciona perfectamente cuando la vista se construye así:PRISM 4 - RegisterViewWithRegion y atributos de exportación personalizados

[Export] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public partial class MyView : UserControl 
{ 
    public MyView() 
    { 
    .... 

La vista obtiene registrado y todo está bien. Tan pronto como cambio la exportación a un atributo de exportación personalizado, la vista ya no se puede encontrar, aunque todavía está en el contenedor. Este atributo de exportación personalizada se toma del comerciante común RI:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 
[MetadataAttribute] 
public class ViewExportAttribute : ExportAttribute, IViewRegionRegistration 
{ 
    public ViewExportAttribute() 
     : base(typeof(object)) 
    { } 

    public ViewExportAttribute(string viewName) 
     : base(viewName, typeof(object)) 
    { 
     ViewName = viewName; 
    } 

    public string RegionName { get; set; } 
    public string ViewName { get; set; } 

} 

y la interfaz es

public interface IViewRegionRegistration 
{ 
    string RegionName { get; } 
    string ViewName { get; } 
} 

Cambiando la exportación de atributos a

[ViewExport(ViewName = "MyView", RegionName = RegionNames.MyRegion)] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public partial class MyView : UserControl 
{ 
    public MyView() 
    { 
    .... 

al llamar RegisterViewWithRegion que arroja un error : Se produjo un error de activación al intentar obtener una instancia de tipo MyView, clave ""

¿Algún consejo? Estuve mirando esta parte del código todo el día sin encontrar una solución.

+0

Más tarde esa noche ... Finalmente descubrí que tiene algo que ver con esta parte en el atributo Custom Export Attribute: ** (typeof (object)) ** - pero aún no se sabe cómo resolver el RegisterViewWithRegion problema ... – okieh

Respuesta

0

El atributo de exportación personalizado pasa typeof(object) al constructor base, que cambia el contrato exportado para que ya no coincida con la importación. Cámbielo para que llame al constructor sin parámetros.

En cuanto al error de activación, deberá observar la excepción con más detalle. La causa raíz probablemente esté allí en alguna parte, quizás enterrada bajo una InnerException.

4

Otro día, de otra manera ... Intentaré responder a mi pregunta a pesar de que solo tengo un conocimiento limitado sobre PRISM. En otras palabras: todavía estoy aprendiendo.

El atributo de exportación personalizado tomado de Stock Trade RI es utilizado por AutoPopulateExportedViewsBehavior. Este comportamiento agrega una vista a su región automáticamente al marcar Exportar atributo para el nombre de la región y luego agrega la vista a la región correspondiente. Pero todas las vistas con este atributo personalizado ahora tienen un nombre de contrato de "objeto" que hace imposible que ServiveLocator las encuentre. Este atributo personalizado es para un escenario con enlaces de región/vista fijos. una solución cuando se trabaja con un atributo de exportación personalizada es conseguir que todas las exportaciones de tipo "objeto" y los metadatos correspondientes:

MyView view; 
var myList = container.GetExports<object, IViewRegionRegistration>(); 
foreach (Lazy<object, IViewRegionRegistration> lazy in myList) 
{ 
    if (lazy.Metadata.ViewName == "MyView") 
    { 
     view = lazy.Value as MyView; 
     region.Add(view); 
     break; 
    } 
} 

Pero creo que cuando se utiliza ViewInjection y Prisma de navegación es mejor sólo tiene que utilizar el valor por defecto [ Exportar] atributo, entonces todo funciona sin problemas.

4

¿Está configurando el catálogo agregado en su programa de arranque MEF? De ser así, ¿está agregando el ensamblado que contiene sus clases ViewExportAttribute y AutoPopulateExportedViewsBehavior? Creo que esto sucede en el programa previo de la StockTraderRI con esta línea:

this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(StockTraderRICommands).Assembly)); 

clase Los StockTraderRICommands se encuentra en la misma Asamblea que las clases ViewExportAttribute y AutoPopulateExportedViewsBehavior.

+0

Tuve el mismo problema que el asker original y esta fue la solución. – Dylan

0

Me encontré exactamente con el mismo problema y fue difícil para un principiante de MEF/PRISM.Okieh describe muy bien el problema, sólo quiero publicar una solución alternativa, que viene de la aplicación de ejemplo StocktraderUI:

La solución funciona (/ parece funcionar) si quieres Ver descubrimiento sin ningún tipo de archivo de configuración, etc. donde tienes que registrar tus puntos de vista.

1. Modificar el evento ViewExport encargo

[Export] 
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 
[MetadataAttribute] 
public sealed class ViewExportAttribute : ExportAttribute, IViewRegionRegistration 
{ 
    public ViewExportAttribute() 
     : base(typeof(UserControl)) 
    { } 

    public string ViewName { get { return base.ContractName; } } 

    public string RegionName { get; set; } 
} 

Se añade el [Exportar] atributo y el constructor base se llama ahora con UserControl en lugar de object. De esta forma, puede ser descubierto por MEF. se añade

2. Modificar AutoPopulateExportedViewsBehavior

[ImportMany(typeof(UserControl))] 
public Lazy<UserControl, IViewRegionRegistration>[] RegisteredViews { get; set; } 

El atributo [ImportMany] y el tipo de la Inicialización Lazy se cambia a UserControl. Ahora, todos los UserControl s con IViewRegionRegistration -implementación de tipo MetaData son importados.

Eso es básicamente eso. Puede usar el [ViewExport] como antes. Tenga en cuenta que las Vistas están limitadas a (sub) tipos de UserControl. Supongo que esto se puede modificar si quieres. Y asegúrese de que su catálogo agregado importe ViewExportAttribute y AutoPopulateExportedViewsBehavior, como dijo Nicolaus ...

De esta manera, no necesita interfaces adicionales para sus vistas y aún puede descubrir todo sin registro codificado.

Espero que ayude y avíseme si me perdí los inconvenientes de mi solución.

Cuestiones relacionadas