2009-11-20 11 views
19

MEF consente di importare più parti tramite l'uso dell'attributo ImportMany. Come determina l'ordine in cui recupera le esportazioni rilevanti e le aggiunge all'enumerabile che si sta compilando? Ad esempio, come importerei più IRules che dovevano sparare in un ordine particolare? L'unico modo che mi viene in mente è quello di avere una proprietà OrderValue in iRule e ordinare manualmente:In che modo MEF determina l'ordine delle sue importazioni?

public class Engine 
{ 
    [ImportMany] 
    public IEnumerable<IRule> Rules { get; set; } 

    public void Run() 
    { 
    // ... 
    // Initialise MEF 
    // ... 

    // 
    // Do I need to manually order Rules here? 
    // 

    foreach (IRule rule in Rules) 
    { 
     // Must execute in a specific order 
     rule.Execute(); 
    } 
    } 
} 
+0

Credo che la vostra ipotesi è corretta - sembra un po 'al di fuori del problema MEF è destinato a risolvere. – GraemeF

risposta

29

Per impostazione predefinita MEF non garantisce alcun ordine delle esportazioni importate. Comunque in MEF puoi fare un po 'di ordinamento usando alcuni metadati e una collezione personalizzata. Per esempio è possibile fare qualcosa di simile:

public interface IRule { } 

[Export(typeof(IRule))] 
[ExportMetadata("Order", 1)] 
public class Rule1 : IRule { } 

[Export(typeof(IRule))] 
[ExportMetadata("Order", 2)] 
public class Rule2 : IRule { } 

public interface IOrderMetadata 
{ 
    [DefaultValue(Int32.MaxValue)] 
    int Order { get; } 
} 

public class Engine 
{ 
    public Engine() 
    { 
     Rules = new OrderingCollection<IRule, IOrderMetadata>(
          lazyRule => lazyRule.Metadata.Order); 
    } 

    [ImportMany] 
    public OrderingCollection<IRule, IOrderMetadata> Rules { get; set; } 
} 

Quindi si avrà una serie di regole che sono ordinate per i metadati. È possibile trovare l'esempio OrderingCollection su http://codepaste.net/ktdgoh.

+0

Grazie! Ho cambiato la mia risposta accettata alla tua. –

+0

Ottima soluzione! – Kilhoffer

+0

Sembra che l'esempio OrderingCollection non sia più disponibile. – tofutim

1

si potrebbe avere il regime d'importazione a vicenda in ordine (utilizzando il modello Decorator), ma poi ogni regola avrà bisogno di conoscere la regola specifica che la precede, che probabilmente non è ciò che desideri.

MEF è lì per aiutarti a scoprire le parti, ciò che fai con loro in seguito dipende da te. Se vuoi ordinare le parti, vai avanti, non c'è niente di sbagliato in questo!

+0

Questo ha confermato quello che mi aspettavo, grazie. –

+0

Per me sembra più efficiente inserire elementi in una lista ordinata piuttosto che generare una lista e quindi ordinare – Assimilater

6

Il modo migliore per ottenere questo ordine in MEF è utilizzare le nostre strutture di metadati. È possibile allegare i propri metadati alle esportazioni che è possibile utilizzare per ordinare e filtrare. I metadati consentono inoltre di ritardare l'istanziazione delle parti finché non sono effettivamente necessarie. Inoltre è possibile creare attributi di esportazione personalizzati che forniscono un modo semplice e pulito di fornire i metadati.

controllare questo link per informazioni su come definire metadati personalizzati e le esportazioni: link text

Si può anche trovare this thread sul nostro forum MEF utili. All'interno troverai una discussione su un approccio AdaptingCollection che ti consente di utilizzare una collezione personalizzata che applica un filtro/ordine di metadati.

HTH Glenn

+0

Grazie Glenn, alla fine ho preso un approccio diverso, ma certamente lo terrò a mente per la prossima volta. Accetterei la tua risposta, ma quando Wes arrivò poco prima con una risposta simile, penso che sarebbe probabilmente più giusto accettare il suo. –

+0

Va bene, Wes ha basato la sua versione sul mio :-) –

Problemi correlati