13

In setting up my Windows Service application to self host using Owin based on this article:

http://www.asp.net/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api

I used this overload of the WebApp.Start method:

WebApp.Start Method (String)

Here is my code:

//(in startup method) 
_server = WebApp.Start<Startup>(BaseAddress);

public class Startup
{
    // This code configures Web API. The Startup class is specified as a type
    // parameter in the WebApp.Start method.
    public void Configuration(IAppBuilder appBuilder)
    {
        // Configure Web API for self-host. 
        var config = new HttpConfiguration();
        config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new
        {
            id = RouteParameter.Optional
        });

        appBuilder.UseWebApi(config);
    }
} 

It works fine, so no complaints.

But what exactly are the requirements of the type parameter of the Start method? It doesn't appear to have any constraints, and I haven't been able to find any documentation on what my options/requirements are on this parameter. Does it look for methods that take IAppBuilder as a parameter? What if I change the name of the Configuration() method to something else? What if I make the method internal? Are there other options I can configure with this class?

Where is all of this this documented? I feel like without the article linked above, I never would have been able to figure out what to implement.

Phil Sandler
  • 27,544
  • 21
  • 86
  • 147
  • I feel the same: http://stackoverflow.com/questions/26368805/why-the-required-startup-class-doest-implements-an-appropriate-interface-like – Yair Nevet Oct 14 '14 at 20:38
  • Worst case you can always read the sources: http://katanaproject.codeplex.com/SourceControl/latest#src/Microsoft.Owin.Hosting/WebApp.cs http://katanaproject.codeplex.com/SourceControl/latest#src/Owin.Loader/DefaultLoader.cs – Tratcher Aug 11 '15 at 08:32
  • Since mine is the only answer, can you mark it as the correct answer please – bikeman868 Oct 03 '20 at 18:30

1 Answers1

7

The WebApp class uses reflection to get a pointer to the Configuration(IAppBuilder) method then calls it. If the class you provide as the generic type argument does not have a Configuration method with the expected arguments then you get an error at run time.

I agree that this is not as discoverable as we would like and I am not sure why the original developers implemented it this way rather than adding a where T: IStartup constraint instead. Not only would this make it more discoverable without documentation, but would also have allowed the compiler to check this at compile time.

The only advantage to this approach is that the OWIN developers can add more methods or methods with different signatures in the future without breaking existing code.

bikeman868
  • 2,236
  • 23
  • 30
  • even if I implement `IStartup`, I can always add more methods, am not saying I will, but I could. Having the interface makes the code more intuitive for me. – Vignesh.N Sep 27 '16 at 11:11
  • My point was that if the OWIN team defined this interface then later the OWIN team added new methods to this interface definition, then your code would no longer compile (until you added implementations of the extra methods). Worse still, if you compiled your code into an assembly and shared it with someone else and they updated to a newer version of OWIN with additional methods in the `IStartup` interface then your code would break at run time. – bikeman868 Sep 28 '16 at 21:08
  • reply makes sense, but I could think of backward compatibility as the only benefit coming out of it. If in the new version, `OWIN` spec introduces a new must implement method, we wouldn't even know about the method and may cause runtime issues, for me compile time issues are cleaner than runtime exceptions. – Vignesh.N Sep 29 '16 at 09:03
  • The point here is that if the OWIN team added support for another `Configuration` method with a different signature then you could implement whichever version of the `Configuration` method you wanted and OWIN would find it through reflection. If the OWIN team had used the interface approach instead and added a new `Configuration` method you would be forced to implement both of them. – bikeman868 Sep 29 '16 at 16:43
  • 2
    In that case they should introduce a new interface and a new Start method with a new constraint (named differently since methods can't differ only in their constraints). Regardless, I'm not sure why they even have the generic type parameter overloads. You can just call `WebApp.Start(BaseAddress, new Startup().Configuration);`, or better yet `WebApp.Start(BaseAddress, Startup.Configuration);` if you make your `Configuration` method `static`. – jam40jeff Mar 17 '17 at 18:36
  • 1
    I agree with you my friend. I wasn't agreeing with what Microsoft did, just explaining how it works and speculating about the reasons for their choices. It has always surprised me how successful Microsoft have been given how poorly designed most of their software is. The strangest part of all is that they have a lot of very bright developers, so it must be an issue with company policy and culture. – bikeman868 Mar 17 '17 at 21:52