MEF:構成された部品からのエクスポートとエクスポートの部分を満たす

StackOverflow https://stackoverflow.com/questions/3061741

質問

シルバーライト4に次のシナリオがあります:

通知サービスがあります

スニペット

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

そして、このサービススニペットの実装

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

client -notificationsサービスのプラグインプロパティは、InotificationsServiceをインポートするインポートクラスによって提供される必要があるとMEFに言うにはどうすればよいですか。

例えば:

スニペット

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

    [Import]
    INotificationService NotificationService;
}

MEFにClientNotificationService.PluginのPRUGINをクライアントクラスによってPRUGINパーツに満足させてほしいと言えますか。

基本的に、IntorificationServiceを使用して、インポートクラスが作成して新しいクラスに作成された場合、またはこれを行うためにMetaデータを使用してこれを使用して代替方法がある場合はいつでも、洞察に感謝します。私はこれにしばらく苦労してきました。

ありがとう

役に立ちましたか?

解決

あなたはあなたのプラグインへのアクセスを許可する代表者をエクスポートすることができます:例:

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

他のヒント

基本的に、InterificationServiceを使用して、インポートクラスが作成して新しいクラスに作成されるたびに、インポートクラスが提供する一意の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);
}

両方のアプローチには、長所と短所が異なります。たとえば、Initialize-on-Importアプローチは簡単ですが、コンポーネントの寿命に追加のフェーズを導入します(「作成されているがまだ初期化されていない」)。

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top