4

API のバージョンごとに個別のヘルプ ページを作成したいと考えています。たとえば、ユーザーは /help?v=1 にアクセスしてバージョン 1.0 のルートを表示し、/help?v=2 にアクセスしてバージョン 2.0 のルートを表示できます。

を使用して、定義されたバージョンのルートのみを返すプロパティをSDammann.WebApi.Versioningに追加し、バージョンを引数としてコンストラクターに追加しました。それから私はこれを試しました:VersionVersionedApiExplorer

config.Services.Add(typeof(IApiExplorer), new VersionedApiExplorer(config, "1"));
config.Services.Add(typeof(IApiExplorer), new VersionedApiExplorer(config, "2"));

しかし、これにより次のエラーが発生します。

The service type IApiExplorer is not supported.
Parameter name: serviceType

構成を機能させるために、サービスのインスタンスを 1 つだけ追加しconfig.Services.Replace(typeof(IApiExplorer), new VersionedApiExplorer(GlobalConfiguration.Configuration, "1"));て、ヘルプ コントローラーをテストできるようにしました。次に、これを試しました:

foreach (var service in Configuration.Services.GetServices(typeof(IApiExplorer))) {
    if (service.GetType() != typeof(VersionedApiExplorer)) continue;

    var explorer = service as VersionedApiExplorer;
    if (explorer.Version == v) {
        apiExplorer = explorer;
    }
}

これにより、上記で受け取ったのと同じエラーが発生します。通常は使用することthis.Configuration.Services.GetApiExplorer()はわかっていますが、それを使用して の適切なインスタンスを取得する方法がわかりませんVersionedApiExplorer。コントローラーで適切なものを直接インスタンス化できることはわかっていApiExplorerますが、可能であればそれを構成ファイルに保持したいと思います。

だから私は2つの質問があります:

  1. VersionedApiExplorerタイプの 2 つのサービスを構成オブジェクトに追加するにはどうすればよいですか?
  2. ヘルプ コントローラーで適切なサービスを取得するにはどうすればよいですか?

それとも、同じ目標を達成するために取ることができるまったく異なるアプローチはありますか?

ありがとうございました!

4

1 に答える 1

0

私は最終的に、質問でほのめかした解決策に行き着きました。この問題にはもっと良い解決策があるように感じますが、これで仕事は完了です。

Versionまず、次のプロパティを追加しましたVersionedApiExplorer

public string Version { get; private set; } 

次に、次InitializeApiDescriptionsのように変更しました。

private Collection<ApiDescription> InitializeApiDescriptions()
{
    Collection<ApiDescription> apiDescriptions = new Collection<ApiDescription>();
    var controllerSelector = configuration.Services.GetHttpControllerSelector();
    IDictionary<string, HttpControllerDescriptor> allControllerMappings = controllerSelector.GetControllerMapping();
    IDictionary<string, HttpControllerDescriptor> controllerMappings = new Dictionary<string, HttpControllerDescriptor>();
    // get only mappings for defined version
    if (allControllerMappings != null && Version != null) {
        foreach (var key in allControllerMappings.Keys) {
            if (key.Substring(0, key.IndexOf('.')) == VersionedControllerSelector.VersionPrefix + Version) {
                controllerMappings.Add(key, allControllerMappings[key]);
            }
        }
    }
    else if (Version == null) {
        controllerMappings = allControllerMappings;
    }

    if (controllerMappings != null)
    {
        foreach (var route in configuration.Routes)
            ExploreRouteControllers(controllerMappings, route, apiDescriptions);
    }
    return apiDescriptions;
}

バージョンを設定するために使用できるメソッドも追加しました。

public void SetVersion(string version) {
    this.Version = version;
    this.apiDescription = new Lazy<Collection<ApiDescription>>(InitializeApiDescriptions);
}

最後に、HelpController次のように変更しました。

public ActionResult Index(string v) {
    return this.View(GetApiExplorer(v).ApiDescriptions);
}

private IApiExplorer GetApiExplorer(string version) {
    if (version == null) {
        version = "1";
    }

    var apiExplorer = this.Configuration.Services.GetApiExplorer() as VersionedApiExplorer;
    if (apiExplorer != null) {
        apiExplorer.SetVersion(version);
    }

    return apiExplorer;
}
于 2015-07-25T01:51:41.713 に答える