2009-06-03 9 views
11

Actualmente mi aplicación WPF importa un papel como ésteCreación de varias instancias de piezas importadas MEF

[Import(typeof(ILedPanel)] 
public ILedPanel Panel { get; set; } 

Pero esto da ma una sola intance de la clase que implementa ILedPanel. Lo que realmente quiero hacer es tener la capacidad de crear tantas instancias que necesite. Tenga en cuenta que solo hay una exportación para ILedPanel incluida con el software en un momento dado.

(Si uso una importación con la lista que me da un caso para cada clase que implementa ILedPanel)

¿Alguna sugerencia?

+0

No estoy seguro de que sea una buena manera pero simplemente fui con Activator.CreateInstance (Panel.GetType()); – TimothyP

Respuesta

9

No está "construido en" apoyo a esta MEF en la actualidad, pero antes de volver al servicio de ubicación, es posible encontrar algo de inspiración aquí: http://blogs.msdn.com/nblumhardt/archive/2008/12/27/container-managed-application-design-prelude-where-does-the-container-belong.aspx

La idea esencial es que se 'importar' el contenedor en el componente que necesita hacer una instanciación dinámica.

Más apoyo directo para este escenario es algo que estamos explorando.

Nick

ACTUALIZACIÓN: MEF ahora tiene soporte experimental para esto. Consulte this blog post para obtener más información.

+0

bueno, si supiera que encontraría la pregunta, no habría dicho nada ... :) –

+1

ACTUALIZACIÓN: esta característica ha llegado a MEF "Vista previa 7" como PartCreator - consulte la wiki del MEF para obtener información (http://mef.codeplex.com/Wiki/View.aspx?title=PartCreator&referringTitle=Home) –

+1

Pero solo para Silverlight parecería – TimothyP

2

Creo que quiere decir que quiere usar MEF en esta instancia como un localizador de servicios en lugar de un contenedor de inyección de dependencia. Trate de mirar ejemplos de ValueResolver

10

no estoy seguro si esto es lo que se está refiriendo a Nicolás, pero se puede importar una clase de fábrica en lugar de una clase de ejemplo, así:

[Import(typeof(ILedPanelFactory)] 
public ILedPanelFactory PanelFactory { get; set; } 

... y luego adelante en el código ...

ILedPanel panel = PanelFactory.BuildPanel(); 
3

en cuanto a la muestra formas de juego que viene con el MEF, existe la clase ShapeFactory:

[Export] 
public class ShapeFactory 
{ 
    private readonly Random random = new Random((int)DateTime.Now.Ticks); 

    [Import] 
    private ICompositionService CompositionService { get; set; } 

    public IShape GetRandomShape() 
    { 
     var shapeRetriever = new ShapeRetriever(); 

     CompositionService.SatisfyImports(shapeRetriever); 

     int randomIndex = random.Next(shapeRetriever.PossibleShapes.Length); 

     return shapeRetriever.PossibleShapes[randomIndex].GetExportedObject(); 
    } 

    private class ShapeRetriever 
    { 
     [ImportMany(RequiredCreationPolicy = CreationPolicy.NonShared)] 
     public Export<IShape, IShapeMetadata>[] PossibleShapes { get; set; } 
    } 
} 

Lo que demuestra la creación de instancias de forma aleatoria "a pedido" ... Creo que en su escenario podría hacer algo similar sin la selección de una implementación aleatoria, ya que sugiere que solo habrá una implementación de ILedPanel registrada.

5

A menos que malinterprete la pregunta, parece que se resolvería simplemente usando CreationPolicy.NonShared.

Esto supone que el código que declara el Panel existe en cualquier lugar que desee un panel. Obtendría una nueva instancia de ILedPanel en cada instancia de cada clase que tuviera esta declaración (la importación).

+0

Eso es verdad. Pero solo hay una clase que implementa ILedPanel con cualquier distribución del software. Así que esa es una sola instancia ... no está limpio, por supuesto – TimothyP

8

Todas las otras respuestas son bastante antiguas, por lo que no mencionan una característica relativamente nueva en MEF llamada ExportFactory.Esta clase genérica permite importar ExportFactory<ILedPanel> y crear tantas instancias como desee siempre que los necesite, por lo que el código se vería así:

[Import(typeof(ILedPanel)] 
public ExportFactory<ILedPanel> PanelFactory { get; set; } 

public ILedPanel CreateNewLedPanelInstance() 
{ 
    return PanelFactory.CreateExport().Value; 
} 

Este método también satisface las importaciones que tiene creadas parte. Puede leer más sobre el uso de la clase ExportFactoryhere.

+0

¡Eso es asombroso, gracias a la actualización! – TimothyP

Cuestiones relacionadas