如果 Startup 在不同的程序集中,AspNet Core AttributeRouting 不会发现路由
AspNet Core AttributeRouting does not discover routes if Startup is in different assembly
我有一个场景,我们有一个 "standardised startup" 用于许多小型 AspNet Core 网站。
一个看似显而易见的解决方案是将 Startup.cs
class 重构为一个单独的通用程序集(如 Infrastructure.Web.Core.Startup
)。然后我们让每个小型 AspNet Core 网站引用它的通用程序集并使用该启动 class 代替:
public static Microsoft.AspNetCore.Hosting.IWebHostBuilder CreateWebHostBuilder( string[] args )
{
return new WebHostBuilder()
.UseKestrel()
.ConfigureServices( collection => { } )
.UseContentRoot( System.IO.Directory.GetCurrentDirectory() )
.UseStartup<Infrastructure.Web.Core.Startup>(); //.UseStartup<Startup>();
}
不知何故,这在路由未命中的意义上破坏了属性路由。没有错误,但不是路由。 当我将 class 复制回网站项目(使用完全相同的代码)时,它再次运行。
作为测试,如果我将 Startup.cs class 包装在本地启动 class 的公共库中(如下所示),它也可以工作:
public class Startup
{
private readonly Infrastructure.Web.Core.Startup _startup;
public Startup( IConfiguration configuration )
{
_startup = new Infrastructure.Web.Core.Startup( configuration );
}
public IConfiguration Configuration => _startup.Configuration;
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices( IServiceCollection services )
{
_startup.ConfigureServices( services );
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure( IApplicationBuilder app, IHostingEnvironment env )
{
_startup.Configure( app, env );
}
}
如果非要我猜的话,这可能与依赖注入有关。
有人有什么建议吗?
仅供参考:它使用典型的 AspNet Core 2.1 项目
更新
顺便说一句,如果我使用继承,它也可以工作,但是派生的 class 必须与网站在同一个项目中。我想这似乎很明显,但我认为为了完整起见我包含了这些信息:
public class Startup : Infrastructure.Web.Core.Startup
{
public Startup( IConfiguration configuration ) : base(configuration)
{
}
}
您可以通过在 Startup.cs
方法中向您的服务添加以下语句来解决此问题。
services.AddApplicationPart(typeof(AnTypeInTheOtherAssembly).Assembly);
这将告诉 View/Controller Discovery 也检查新位置。包含 Startup.cs
文件的项目将是启动项目,所有其他项目将只是参考和库或类似项目。
从 .Net Core 3 开始,您可以使用名为 Razor Class Libraries
的东西,请参阅 MSDN。这会自动将您的控制器和视图添加到发现中,它还具有调试支持并且将像普通的 Class 库一样工作。
我有一个场景,我们有一个 "standardised startup" 用于许多小型 AspNet Core 网站。
一个看似显而易见的解决方案是将 Startup.cs
class 重构为一个单独的通用程序集(如 Infrastructure.Web.Core.Startup
)。然后我们让每个小型 AspNet Core 网站引用它的通用程序集并使用该启动 class 代替:
public static Microsoft.AspNetCore.Hosting.IWebHostBuilder CreateWebHostBuilder( string[] args )
{
return new WebHostBuilder()
.UseKestrel()
.ConfigureServices( collection => { } )
.UseContentRoot( System.IO.Directory.GetCurrentDirectory() )
.UseStartup<Infrastructure.Web.Core.Startup>(); //.UseStartup<Startup>();
}
不知何故,这在路由未命中的意义上破坏了属性路由。没有错误,但不是路由。 当我将 class 复制回网站项目(使用完全相同的代码)时,它再次运行。
作为测试,如果我将 Startup.cs class 包装在本地启动 class 的公共库中(如下所示),它也可以工作:
public class Startup
{
private readonly Infrastructure.Web.Core.Startup _startup;
public Startup( IConfiguration configuration )
{
_startup = new Infrastructure.Web.Core.Startup( configuration );
}
public IConfiguration Configuration => _startup.Configuration;
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices( IServiceCollection services )
{
_startup.ConfigureServices( services );
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure( IApplicationBuilder app, IHostingEnvironment env )
{
_startup.Configure( app, env );
}
}
如果非要我猜的话,这可能与依赖注入有关。
有人有什么建议吗?
仅供参考:它使用典型的 AspNet Core 2.1 项目
更新 顺便说一句,如果我使用继承,它也可以工作,但是派生的 class 必须与网站在同一个项目中。我想这似乎很明显,但我认为为了完整起见我包含了这些信息:
public class Startup : Infrastructure.Web.Core.Startup
{
public Startup( IConfiguration configuration ) : base(configuration)
{
}
}
您可以通过在 Startup.cs
方法中向您的服务添加以下语句来解决此问题。
services.AddApplicationPart(typeof(AnTypeInTheOtherAssembly).Assembly);
这将告诉 View/Controller Discovery 也检查新位置。包含 Startup.cs
文件的项目将是启动项目,所有其他项目将只是参考和库或类似项目。
从 .Net Core 3 开始,您可以使用名为 Razor Class Libraries
的东西,请参阅 MSDN。这会自动将您的控制器和视图添加到发现中,它还具有调试支持并且将像普通的 Class 库一样工作。