0

2 つの VSPackage があります。最初のものは、グローバル サービスを提供します。どちらの VSPackages もサービスを使用します。

サービスは、 MSDN の「How To: Register a Service」で説明されているように定義されています。ComVisibleAttribute は省略しました。ハウツーでは、サービスをアンマネージ コードで使用できるようにする必要がある場合にのみ必要であると述べていますが、そうではありません。インターフェースは次のようなものです

[Guid("5A72348D-617B-4960-B07A-DC6CC5AA7675")]
public interface SMessageBus {}

[Guid("04A499BA-CE09-48AF-96D5-F32DEAF0754C")]
public interface IMessageBus { ... }

サービス提供パッケージは、MSDN の「How To: Provide a Service」に従っています。次のようになります。

[<package atttributes>]
[ProvideService(typeof(SMessageBus))]
public sealed class MessageBusProviderPackage : Package
{
  public MessageBusProviderPackage()
  {
    var serviceContainer = this as IServiceContainer;
    var serviceCreatorCallback = new ServiceCreatorCallback(CreateMessageBusService);
    serviceContainer.AddService(typeof(SMessageBus), serviceCreatorCallback, true);
  }

  private object CreateMessageBusService(IServiceContainer container, Type serviceType)
  {
    // this gets called and returns a new bus instance
    return (serviceType == typeof(SMessageBus)) ? new MyMessageBus() : null;
  }

  protected override void Initialize()
  {
    // this is called after the package was constructed
    // the call leads to the service being created by CreateMessageService()
    var messageBus = GetService(typeof(SMessageBus)) as IMessageBus;
    // the bus is retrieved correctly
    ...
  }
}

この他のパッケージは次のように宣言されています

[<package attributes>]
[ProvideAutoLoad(VSConstants.UICONTEXT.NoSolution_string)]
public sealed class MessageGeneratorPackage : Package
{
  protected override void Initialize()
  {
    // the call below is reached first, in its course the provider is loaded
    var service = GetService(type(SMessageBus));
    // this point is reached last, but service is null
    ...
  }
}

起動フェーズをデバッグしたところ、MessageGeneratorPackage が最初に作成および初期化されることがわかりました。これは、パッケージが配置されたことを意味します。Initialize() の GetService() 呼び出しに到達すると、VS はサービス プロバイダをロードします。つまり、ProvideServiceAttribute は MessageBusProviderPackage を SMessageBus サービスのプロバイダとして正しくマークします。プロバイダー パッケージがインスタンス化され、その Initialize() メソッドが呼び出され、サービスが正常に取得されます。その後、コンシューマ パッケージの初期化が続行されますが、サービス リクエストは null を返します。MSDN の「How To: Troubleshoot Services」に記載されているすべての要件が満たされているように思えます。私が欠けているものを誰か教えてもらえますか?

4

1 に答える 1

1

自分で答えを見つけました... Initialize() のオーバーライドは base.Initialize() を呼び出す必要があります。これは、登録されたサービスが実際に親サービスコンテナーに昇格されるためです。

于 2013-10-15T12:56:15.680 に答える