2011-04-04 7 views
6

Dado un objeto arbitrario ya existente al que se le atribuyen etiquetas [Importar], ¿qué baile de pandereta debo hacer para que MEF complete las importaciones?Importaciones satisfactorias para un objeto existente usando MEF

Gran parte de la documentación del blog parece estar construida contra versiones de vista previa de MEF y ya no funciona - Estoy usando la versión que es parte de .NET 4.0 (o alternativamente, MEF 2.0 Preview 3).

AggregateCatalog _catalog; 
CompositionContainer _container; 

public void Composify(object existingObjectWithImportTags) 
{ 
    lock(_container) { 
     var batch = new CompositionBatch(); 

     // What do I do now?!?! 
    } 
} 
+0

felicitaciones si sabía cómo deletrear pandereta en el primer intento – toddmo

Respuesta

6

MEF resuelve importaciones (a través de la propiedad o la inyección de constructor), a lo largo de un poco con sus propias dependencias, de exportan tipos en los conjuntos registrados registrados en el catálogo (que incluye el conjunto actual).

Si desea crear un objeto directamente (usando la palabra clave new), o en el caso de la exportación no estaba preparada en el momento de la creación, se puede utilizar el recipiente para satisfacer las importaciones de una objeto, utilizando:

_container.SatisfyImportsOnce(yourObject); 

He creado un pequeño escenario haciendo precisamente eso. Aquí está el código:

public class Demo 
{ 
    private readonly CompositionContainer _container; 

    [Import] 
    public IInterface Dependency { get; set; } 

    public Demo(CompositionContainer container) 
    { 
     _container = container; 
    } 

    public void Test() 
    { 

     //no exported value, so the next line would cause an excaption 
     //var value=_container.GetExportedValue<IInterface>(); 

     var myClass = new MyClass(_container); 

     //exporting the needed dependency 
     myClass.Export(); 

     _container.SatisfyImportsOnce(this); 

     //now you can retrieve the type safely since it's been "exported" 
     var newValue = _container.GetExportedValue<IInterface>(); 
    } 
} 

public interface IInterface 
{ 
    string Name { get; set; } 
} 

[Export(typeof(IInterface))] 
public class MyClass:IInterface 
{ 
    private readonly CompositionContainer _container; 

    public MyClass() 
    { 

    } 
    public MyClass(CompositionContainer container) 
    { 
     _container = container; 
    } 

    #region Implementation of IInterface 

    public string Name { get; set; } 

    public void Export() 
    { 
     _container.ComposeExportedValue<IInterface>(new MyClass()); 
    } 

    #endregion 
} 

Ahora, sólo tiene que utilizar new Tests(new CompositionContainer()).Test(); para iniciar la demostración.

Espero que esto ayude :)

+0

No, esto no funciona, SatisfyImportsOnce toma ComposablePart - este es mi problema central. –

+0

hay una sobrecarga (o más bien un método de extensión) que toma cualquier objeto para satisfacer sus importaciones. Probé el ejemplo exacto que puse aquí, y funcionó bien;) – AbdouMoumen

+0

Ah, necesitas una declaración "using System.ComponentModel.Composition" (no solo .Hosting) - ¡gracias por la sugerencia! –

3
_container.ComposeParts(existingObjectWithImportTags); 

ComposeParts es un método de extensión que busca.

Simplemente crea un CompositionBatch y llama a AddPart (AttributedModelServices.CreatePart (attribuObject)) y luego llama a _container.Compose (batch).

Cuestiones relacionadas