代码之家  ›  专栏  ›  技术社区  ›  Pop Catalin

MEF:使用组合零件和从组合零件导出满足导出零件

  •  2
  • Pop Catalin  · 技术社区  · 14 年前

    我在Silverlight 4中有以下场景:

    我有通知服务

    代码段

    [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满足ClientNotificationService.Plugin部分和客户端类导出的IPlugin。

    或者如果有其他的方法,比如使用元数据来做这件事,我会很感激任何的见解。我已经挣扎了一段时间了。

    2 回复  |  直到 14 年前
        1
  •  1
  •   Matthew Abbott    14 年前

    您可以导出允许您访问插件的委托,例如:

    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
  •  2
  •   Wim Coenen    14 年前

    基本上我想要 通知服务,接收 导入服务器提供的唯一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"; 
            }
        }
    }
    

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

    两种方法都有不同的优点和缺点。例如,导入时初始化方法很简单,但它在组件生命周期中引入了一个额外的阶段(“已创建但尚未初始化”)。

    实例。如果需要清理,工厂方法也将处理容器中物品的责任转移给工厂客户。