Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move Startup.cs to Class Library (Package) Project - ASP.NET 5

I'm working in a MVC 6 project, and moved my Startup.cs class from the Web Project to an Infraestructure Project, which is a Class Libary Package. I also added the packages required by the class (exactly the same as the Web Project) in Infraestructure/project.son:

"Microsoft.AspNet.Diagnostics": "1.0.0-beta8",
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-beta8",
"Microsoft.AspNet.Mvc": "6.0.0-beta8",
"Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-beta8",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-beta8",
"Microsoft.AspNet.StaticFiles": "1.0.0-beta8",
"Microsoft.AspNet.Tooling.Razor": "1.0.0-beta8",
"Microsoft.Framework.Configuration.Json": "1.0.0-beta8",
"Microsoft.Framework.Logging": "1.0.0-beta8",
"Microsoft.Framework.Logging.Console": "1.0.0-beta8",
"Microsoft.Framework.Logging.Debug": "1.0.0-beta8",
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-beta8"

But when I run the app get the following exception:

A type named 'StartupDevelopment' or 'Startup' could not be found in assembly 'UI.Web'.
at Microsoft.AspNet.Hosting.Startup.StartupLoader.FindStartupType

I didn't find any way for specifying the Startup.cs location to my another assembly.

like image 799
Franco Avatar asked Oct 17 '15 06:10

Franco


1 Answers

ASP .Net 5 uses a new hosting framework which will look for a class named Startup (Or Startup+environment as in StartupDevelopment, as explained in the docs).

This hosting framework uses the class Microsoft.AspNet.Hosting.WebHostBuilder in order to create the IHostingEngine, but more interestingly allows specifying the assembly where this class should be found.

  • Looking at the docs, you will see this is possible by providing a configuration value with the key Hosting:Application.

The process for specifying this value depends on which version of the framework you are using. In case of beta7 and earlier, it also depends if you are using IIS or a dnx command to run the application.


BETA8

One of the latest changes in beta8 is precisely related with the IIS Hosting model.

  • The old Helios hosting component has been abandoned, and a new approach is used which allows running a dnx command when using IIS hosting. More details in the announcement

This means in beta8 the process of setting the configuration value Hosting:Application will be the same regardless of whether you are using IIS or a dnx command:

  • You can directly add an argument to the dnx command line definition in your project.json:

    "commands": {
      "web": "Microsoft.AspNet.Server.Kestrel --Hosting:Application ClassLibrary1",
    },
    
  • You can add a config argument to the dnx command line definition, which points to a json file where you can specify arguments used for starting the hosting:

    //project.json
    "commands": {
      "web": "Microsoft.AspNet.Server.Kestrel --config hosting.json",
    },
    
    //hosting.json
    {  
      "Hosting:Application": "ClassLibrary1",
    }         
    
  • If you don't specify a config file, the framework will still look for a file named Microsoft.AspNet.Hosting.json in your base folder. You can create that file and specify the startup class there.

    • In case you are curious, you can see this behavior defined in the Program class of the Microsoft.AspNet.Hosting assembly.

BETA 7

In beta7 and earlier, the process for specifying this configuration value was different depending if you were using IIS or a dnx command.

Using a dnx command

This is very similar to the way I have explained in the beta8 section except, except that hosting configuration file expected by the framework is an .ini file. (And if is not provided it won't look for by default for a Microsoft.AspNet.Hosting.json file)

Basically if you open your project.json you will see a command named web defined like the following:

"commands": {
  "web": "Microsoft.AspNet.Hosting --config hosting.ini"
},

You have 2 main options for adding the Hosting:Application configuration key:

  • Add the parameter directly to the command definition

    "commands": {
      "web": "Microsoft.AspNet.Hosting --config hosting.ini --Hosting:Application ClassLibrary1"
    },
    
  • Add it to the hosting.ini file:

    server=Microsoft.AspNet.Server.WebListener
    server.urls=http://localhost:5000
    Hosting:Application=ClassLibrary1
    

You can understand better the way this will work by looking at the WebHostBuilder class, which is used by the Program.Main function in Microsoft.AspNet.Hosting

Now you will need to tell VS to run the command instead of IIS. Which you can do by selecting the default run action: Choosing web or IISExpress when running project

You can also configure the properties for each of those profiles in the project properties pages: Profile properties pages

  • If you want to use the web command instead of IISExpress you will probably want to select the Launch URL action, entering the root url for your site (Which should match the one you defined in your hosting.ini file).

  • You also have the option of adding command line arguments, so you could define here the startup assembly entering --Hosting:Application=ClassLibrary1. (Although defining it here means it will only be applied when starting the app from visual studio)

  • These settings are saved into a file launchSettings.json in the Properties folder of your project. (Will be created the first time you change the default settings) Of course you can also manually modify this file.

When you run/debug your project using the web command you will see a dnx window opened, the browser launched (If you selected Launch URL in the web profile) and the Startup class in the specified assembly is used. For example I moved Startup to a project named ClassLibrary1: Launching web command

Using IISExpress

Since this is still using the old Helios hosting component, the process is different than when using a dnx command.

I have dig a bit in the code used to start the application using IISExpress and I have found that it is using RuntimeHttpApplication.ApplicationStart in the assembly Microsoft.AspNet.Loader.IIS.

  • This class is the one calling into the new Microsoft.AspNet.Hosting, more concretely it is creating the WebHostBuilder, calling its Build method to get the IHostingEngine and finally calling Start in the engine.

Interestingly the configuration provided to the WebHostBuilder can include a file named Microsoft.AspNet.Hosting.ini which must be found in the root path of the website. (Since it is looking for the file using IHttpApplication.MapPath("/Microsoft.AspNet.Hosting.ini")).

This means you can create a file named Microsoft.AspNet.Hosting.ini (case insensitive) inside the wwwroot folder of your application, containing a single line like follows:

Hosting:Application=ClassLibrary1
like image 174
Daniel J.G. Avatar answered Sep 19 '22 21:09

Daniel J.G.