2015-06-24 3 views
0

Каков наилучший способ разработки архитектуры плагинов на основе MEF, которая имеет зависимости между плагинами? Например:Состав MEF с несколькими взаимозависимыми частями

class MainForm 
    { 
    CompositionContainer container; 

    [ImportMany] 
    IEnumerable<Lazy<IWindow>> windows; 

    public MainForm() 
    { 
     this.container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly())); 
     this.container.ComposeParts(this); 
    } 

    public void DoSomething() 
    { 
     foreach (var winPart in windows) 
     { 
     Debug.WriteLine(winPart.Value.Name); 
     } 
    } 
    } 


    interface IWindow 
    { 
    string Name { get; } 
    } 

    delegate void AnEvent(object sender, EventArgs e); 
    interface IEventManager 
    { 
    event AnEvent AnEvent; 
    void OnAnEvent(object sender, EventArgs eventArgs); 
    } 

    [Export(typeof(IEventManager))] 
    class EventManager : IEventManager 
    { 
    public event AnEvent AnEvent = delegate { }; 
    public void OnAnEvent(object sender, EventArgs eventArgs) { AnEvent(sender, eventArgs); } 
    } 

    [Export(typeof(IWindow))] 
    class Window1 : IWindow 
    { 
    [Import] 
    IEventManager eventMgr; 

    public Window1() { } 

    public string Name 
    { 
     get 
     { 
     eventMgr.OnAnEvent(this, new EventArgs()); 
     return "Window1"; 
     } 
    } 
    } 

    [Export(typeof(IWindow))] 
    class Window2 : IWindow 
    { 
    [Import] 
    IEventManager eventMgr; 

    public Window2() { this.eventMgr.AnEvent += eventMgr_AnEvent; } 

    void eventMgr_AnEvent(object sender, EventArgs e) 
    { 
     Debug.WriteLine("Event from Window 2"); 
    } 

    public string Name { get { return "Window2"; } } 
    } 

В Window2 конструктор this.eventMgr является недействительным. Я ожидаю, что он будет составлен MainForm. Один из подходов состоит в том, чтобы иметь несколько CompositionContainers, но если вы это делаете, есть два экземпляра EventManager, а не один общий экземпляр. Какой был бы лучший способ сделать это?

ответ

0

В этом вопросе более подробно учитываются взаимозависимости. Ключом является наличие сборок в каталоге, переданном в CompositionContainer, который используется для компоновки деталей. Затем следующий код помог одному плагину получить доступ к другому плагину:

[Export(typeof(IWindow))] 
    class Window2 : IWindow 
    { 
    IEventManager eventMgr; 

    [ImportingConstructor] 
    public Window2([Import(typeof(IEventManager))]IEventManager mgr) 
    { 
     this.eventMgr.AnEvent += eventMgr_AnEvent; 
    } 

    void eventMgr_AnEvent(object sender, EventArgs e) 
    { 
     Debug.WriteLine("Event from Window 2"); 
    } 

    public string Name { get { return "Window2"; } } 
    }