4

我想为我的 API 的每个版本创建一个单独的帮助页面。例如,用户可以转到 /help?v=1 来查看 1.0 版路由,而 /help?v=2 可以查看 2.0 版路由。

使用SDammann.WebApi.Versioning,我添加了一个Version属性,VersionedApiExplorer该属性将仅返回已定义版本的路由,并将版本添加为构造函数的参数。然后我尝试了这个:

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

我只添加了一个服务实例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直接在控制器中实例化适当的,但如果可能的话,我更愿意将它保存在我的配置文件中。

所以我有两个问题:

  1. 如何VersionedApiExplorer向我的配置对象添加两种类型的服务?
  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 回答