我在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满足客户端类导出的IPlugin的ClientNotificationService.Plugin部分。
基本上我希望NotificationService接收导入类提供的唯一ID,无论何时创建并编写新类, 或者如果有替代方法,比如使用元数据来做这件事,我会很感激任何见解。我一直在努力解决这个问题。
由于
答案 0 :(得分:2)
基本上我想要的 NotificationService,收到一个 导入提供的唯一ID class,无论何时创建和 由新班组成
您可以将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。但是,当然你必须保持配置,这可能会很痛苦。
答案 1 :(得分: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;
}