2

Silverlight4には次のシナリオがあります。

通知サービスがあります

スニペット

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

およびこのサービスの実装Snippet

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

ClientNotificationServiceのPluginプロパティは、INotificationsServiceをインポートするインポートクラスによって提供される必要があることをMEFにどのように伝えることができますか。

例えば:

スニペット

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

    [Import]
    INotificationService NotificationService;
}

MEFがClientクラスによってエクスポートされたIPluginでClientNotificationService.Plugin部分を満たすようにするにはどうすればよいですか。

基本的に、NotificationServiceは、インポートするクラスによって提供される一意のIDを受け取り、新しいクラスが作成および作成されるたびに、またはメタデータを使用してこれを行うなどの代替メソッドがある場合は、洞察をいただければ幸いです。私はしばらくこれに苦労してきました。

ありがとう

4

2 に答える 2

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"; 
        }
    }
}

もう1つのオプションは、IDパラメーターを受け入れるファクトリをインポートすることです。

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

どちらのアプローチにも、長所と短所が異なります。たとえば、インポート時に初期化するアプローチは簡単ですが、コンポーネントの存続期間に追加のフェーズが導入されます(「作成されたがまだ初期化されていない」)。

ファクトリアプローチはこれを回避しますが、必要なインスタンスが1つだけであるという事実をあいまいにします。クリーンアップが必要な場合、ファクトリアプローチは、コンテナからファクトリクライアントに物を処分する責任も移します。

さらに別のオプションは、MEFから別のIoCコンテナーに切り替えることです。これにより、Castle Windsorのように、コンポーネントの登録と依存関係の解決をよりきめ細かく制御できます。ただし、もちろん構成を維持する必要があり、これは面倒な場合があります。

于 2010-06-18T09:47:50.360 に答える
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;
}
于 2010-06-18T08:47:18.447 に答える