Search code examples
asp.net-web-apicontrollerswaggerswashbuckleapi-versioning

How can i set the api version on a generic controller when loading a plugin?


I have some plugin's which are basically input and output type definitions. I have a generic controller which i can add to the mvc pipeline. All works fine.

but I'm having trouble setting the api version on this generic controller. I know you can set this based upon an attribute on top of the controller class. But since you can't have this dynamic (attribute) don't allow it, i have no way to set the version for each instance of the generic controller.

Currently i just compile the controller for each instance on runtime and register i using the roslyn compiler.

is there a way to set the api-version somewhere in the pipeline of registering controllers in the mvc pipeline and endup with different api versions endpoints.


Solution

  • This can be achieved by using the Conventions API. It was designed to support this exact type of scenario:

    https://github.com/microsoft/aspnet-api-versioning/wiki/API-Version-Conventions

    This will only work on closed-generics, but it shouldn't be too much work to make that happen. Here's a couple of basic examples:

    // typed, closed generic
    options.Conventions.Controller<GenericController<PlugIn1>>().HasApiVersion(1,0);
    
    // untyped, closed generic
    var controllerType = typeof(GenericController<>).MakeGenericType(new []{typeof(PlugIn1)});
    options.Conventions.Controller(controllerType).HasApiVersion(1,0);
    

    You can also author your own custom conventions a la IControllerConvention. This approach could be used to version all controllers that inherit from GenericController<>. Then you just need to add it to the conventions like this:

    options.Conventions.Add(new PlugInControllerConvention());
    

    Hopefully that's enough to get you started. Feel free to ask more questions.