2010-05-30 22 views
2

我正在開發一個可以與各種硬件通信的程序。由於它溝通和控制的項目性質各不相同,因此我需要爲每個不同的硬件都有不同的「驅動程序」。這讓我認爲MEF將是一種很好的方式,可以將這些驅動程序作爲即使在產品發佈後也可以添加的插件。如何使用未硬編碼到程序集中的數據填充MEF插件?

我已經看過很多如何使用MEF的例子,但是我一直無法找到答案的問題是如何用外部數據填充MEF插件(例如,從數據庫)。所有我能找到有「數據」的例子硬編碼到組件,如下例所示:

[Export(typeof(IRule))] 
public class RuleInstance : IRule 
{ 
    public void DoIt() {} 

    public string Name 
    { 
     get { return "Rule Instance 3"; } 
    } 

    public string Version 
    { 
     get { return "1.1.0.0"; } 
    } 

    public string Description 
    { 
     get { return "Some Rule Instance"; } 
    } 
} 

如果我想的名稱,版本和說明,來自數據庫?我如何告訴MEF從哪裏得到這些信息?

我可能會丟失一些非常明顯的東西,但我不知道它是什麼。

回答

3

你將不得不要麼將信息傳遞給插件它通過屬性加載之後:

[Export(typeof(IRule))] 
public class RuleInstance : IRule 
{ 
    puliic void DoIt() 
    { } 

    public string Name { get; set; } 
} 

public class Program 
{ 
    [Import(typeof(IRule))] 
    public IRule instance { get; set; } 

    public void Run() 
    { 
     // Load the assemblies here 

     instance.Name = "Rule Instance 3"; 
    }    
} 

或與該插件可以請求雖然主機接口的變量。您可以通過屬性或通過構造函數參數傳遞IHost實例,但構造函數參數對於MEF並不簡單。這是通過屬性:

[Export(typeof(IRule))] 
public class RuleInstance : IRule 
{ 
    puliic void DoIt() 
    { } 

    public void Initialise() 
    { 
     // Load our name from the host, this cannot be done in the constructor 
     string name = Host.GetName(/* some parameters? */) 
    } 


    public IHost Host { get; set; } 
    public string Name { get; set; } 
} 

public interface IHost 
{ 
    string GetName(/* some parameters? */); 
} 

public class Program : IHost 
{ 
    [Import(typeof(IRule))] 
    public IRule instance { get; set; } 

    public void Run() 
    { 
     // Load the assemblies here  

     // Make sure the plugins know where the host is... 
     instance.Host = this; 
    }    
} 

你也「導出」數據庫接口和「進口」到它需要訪問數據庫任何插件...

+0

是的,那些是有道理的。這些看起來很簡單。在您的主機示例中,您使用了「Initialize()」函數。如果MEF在導出的可組合部分中存在,MEF是否總是調用該函數? – hjoelr 2010-05-30 21:40:14

+1

@hjoelr不,MEF不會自動調用該函數。你必須從主機調用它。您也可以導出主機,從插件導入主機,然後在插件上實現IPartImportsSatisfiedNotification接口,並讓他們在OnImportsSatisfied方法中執行初始化。 – 2010-05-30 22:23:47

1

您可以隨時導出單個值(通過合同名稱),這裏是一個例子:

public class Configuration 
{ 
    [Export("SomeValue")] 
    public string SomeValue 
    { 
    get { /* return value from database perhaps? */ } 
    } 
} 

[Export(typeof(IRule))] 
public class RuleInstance : IRule 
{ 
    [Import("SomeValue")] 
    public string SomeValue { get; private set; } 
} 
相關問題