C# MEF:在导出时使用部件并从组成部件导出

C# MEF:在导出时使用部件并从组成部件导出,c#,.net,silverlight,mef,composition,C#,.net,Silverlight,Mef,Composition,我在Silverlight 4中有以下场景: 我有一个通知服务 片段 [InheritedExport] public interface INotificationsService : IObservable<ReceivedNotification> { void IssueNotifications(IEnumerable<ClientIssuedNotification> notifications); } public class Client {

我在Silverlight 4中有以下场景:

我有一个通知服务

片段

[InheritedExport]
public interface INotificationsService : IObservable<ReceivedNotification>
{
    void IssueNotifications(IEnumerable<ClientIssuedNotification> notifications);
}
public class Client
{
    [Export]
    IPlugin Current { get; set; }

    [Import]
    INotificationService NotificationService;
}
我如何告诉MEF ClientNotificationService的Plugin属性必须由导入INotificationsService的导入类提供

例如:

片段

[InheritedExport]
public interface INotificationsService : IObservable<ReceivedNotification>
{
    void IssueNotifications(IEnumerable<ClientIssuedNotification> notifications);
}
public class Client
{
    [Export]
    IPlugin Current { get; set; }

    [Import]
    INotificationService NotificationService;
}
我怎么能说我希望MEF满足ClientNotificationService.Plugin部分和客户端类导出的IPlugin

基本上,我希望NotificationService在创建并组合到新类时接收导入类提供的唯一ID, 或者,如果有其他方法,比如使用元数据,我会很感激任何见解。我已经为此挣扎了一段时间


谢谢

您可以导出一个代理,允许您访问您的插件,例如:

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;
}
公共类客户端
{
[导出(“PluginDelegate”)]
IPlugin GetPlugin()
{
返回新的SamplePlugin();
}
[进口]
public INotificationService NotificationService{get;set;}
}
[PartCreationPolicy(CreationPolicy.NonShared)]
公共类ClientNotificationService:INotificationService
{
[导入(“PluginDelegate”)]Func PluginDelegate;
}
基本上我想要 通知服务,以接收 导入服务器提供的唯一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);
}
另一个选项是导入接受ID参数的工厂:

public interface INotificationsServiceFactory
{
   INotificationsService Create(string ID);
}
这两种方法各有优缺点。例如,导入时初始化方法很简单,但它在组件生命周期中引入了一个额外的阶段(“已创建但尚未初始化”)

工厂方法避免了这一点,但它掩盖了一个事实,即您只需要一个实例。如果需要清理,工厂方法还将处理容器中物品的责任转移给工厂客户


还有一种选择是从MEF切换到另一个IoC容器,它可以让您对组件注册和依赖项解析进行更细粒度的控制,如Castle Windsor。当然,您必须维护配置,这可能会很痛苦。

谢谢您的回答,但我真正需要的是某种“范围”解决方案,一种能够自动解决此类问题的解决方案。我需要对这个问题进行更多的研究,以了解如何实施这样的解决方案。