2010-06-17 29 views
2

我已經在Silverlight 4以下情形的出口和手託部分:MEF:使用出口從組成部分

我有一個通知服務

片段

[InheritedExport] 
public interface INotificationsService : IObservable<ReceivedNotification> 
{ 
    void IssueNotifications(IEnumerable<ClientIssuedNotification> notifications); 
} 

,並與實施的服務 代碼段

[PartCreationPolicy(CreationPolicy.NonShared)] 
public class ClientNotificationService : INotificationsService 
{ 
    [Import] 
    IPlugin Plugin { get; set; } 
    ... 
} 

如何我可以對MEF說,ClientNotificationService的Plugin屬性必須由導入INotificationsService的導入類提供。

例如:

片段

public class Client 
{ 
    [Export] 
    IPlugin Current { get; set; } 

    [Import] 
    INotificationService NotificationService; 
} 

我怎麼能說我想MEF由客戶端類,以滿足與出口IPlugin的ClientNotificationService.Plugin部分。

基本上我希望NotificationService接收由導入類提供的唯一ID,只要它被創建並組成一個新的類, 或者如果有替代方法,就像使用元數據來做到這一點一樣感謝任何見解。我一直在努力。

感謝

回答

1

你可以導出一個委託,它將允許你訪問你的插件,如:

public class Client 
{ 
    [Export("PluginDelegate")] 
    IPlugin GetPlugin() 
    { 
     return new SamplePlugin(); 
    } 

    [Import] 
    public INotificationService NotificationService { get; set; } 
} 

[PartCreationPolicy(CreationPolicy.NonShared)] 
public class ClientNotificationService : INotificationService 
{ 
    [Import("PluginDelegate")] Func<IPlugin> PluginDelegate; 
} 
2

基本上我想要的 NotificationService,接收由提供 唯一ID導入 類,每當它創建時 組成一個新類

你可以在ID(以及它需要初始化的事實)添加到INotificationsService合同:

public interface INotificationsService : IObservable<ReceivedNotification> 
{ 
    /// <summary> 
    /// Gets or sets the ID for this notification service. May only be set once. 
    /// </summary> 
    /// <exception cref="InvalidOperationException"> 
    /// The setter was called more than once, or the getter was called before the 
    /// ID was initialized. 
    /// </exception> 
    string ID { get; set; } 

    void IssueNotifications(IEnumerable<ClientIssuedNotification> notifications); 
} 

的進口就可以是這樣的:

public class Client 
{ 
    private readonly INotificationsService _notificationsService; 

    [Import(typeof(INotificationService), 
     RequiredCreationPolicy = CreationPolicy.NonShared)] 
    public INotificationsService NotificationsService 
    { 
     get 
     { 
      return _notificationsService; 
     } 
     set 
     { 
      _notificationsService = value; 
      _notificationsService.ID = "SomeID"; 
     } 
    } 
} 

另一個選項是導入一個接受ID參數的工廠:

public interface INotificationsServiceFactory 
{ 
    INotificationsService Create(string ID); 
} 

這兩種方法都有不同的優缺點。例如,初始化導入方法非常簡單,但它在組件生命週期中引入了一個額外階段(「已創建但尚未初始化」)。

工廠方法避免了這一點,但它掩蓋了一個事實,即您只需要一個實例。如果需要清理,工廠方法也會將處理貨物從容器處理到工廠客戶的責任轉移。

還有一種選擇是從MEF切換到另一個IoC容器,它可以更好地控制組件註冊和依賴關係解析,如Castle Windsor。但是,那麼你將不得不維持當然的配置,這可能是一個痛苦。

+0

感謝您的回答,但我真正需要的是'範圍'解決方案的一個王者,一個能夠自動解決此類問題的解決方案。我需要更多地研究這個問題,看看我該如何實施這樣的解決方案。 – 2010-06-21 06:36:08