我正在使用Asp.Net 5和MVC6在洋葱架构(OA)之后的电子商务网站上工作,这样我们就可以在层之间进行松散耦合.我还想在自己的程序集中解耦启动代码,而不是将它放在MVC项目中.
在beta7中很容易将Startup.cs移动到类库(Bootstrapper),如here所述.使用上述方法的一个有趣的事实是我没有必要从MVC项目引用Bootstrapper程序集.在运行时,在IISExpress下托管,通过程序集扫描,它能够找到Microsoft.AspNet.Hosting.ini文件中提到的Bootstrapper程序集.这可以通过在global.json中指定位置来实现
{
"projects": [ "Source/Projects","Source/Bootstrapper" ],"sdk": {
"architecture": "x64","runtime": "clr","version": "1.0.0-beta7"
}
}
Bootstrapper项目将引用所有其他项目,如基础设施,服务等,以便连接依赖注入.
遵循洋葱架构规则,不在MVC项目中引用Bootstrapper项目的原因是避免直接从MVC项目访问基础架构代码.所以这一切都正常,直到我今天早上升级到Beta8.
随着托管模型从IIS更改为Kestrel,我不得不重构global.json和project.json文件,如下所示
global.json
{
"projects": [ "Source/Projects","version": "1.0.0-beta8"
}
}
project.json
{
"dependencies": {
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-beta8","Microsoft.AspNet.Server.Kestrel": "1.0.0-beta8","....",},"commands": {
"web": "Microsoft.AspNet.Server.Kestrel"
}
}
进行上述更改后,无论是使用dnx命令还是直接通过Visual Studio运行,我都会收到以下错误
Internal Server Error System.InvalidOperationException A
type named ‘StartupDevelopment’ or ‘Startup’ could not be found in
assembly ‘EcommerceMvcApp’. at
Microsoft.AspNet.Hosting.Startup.StartupLoader.FindStartupType(String
startupAssemblyName,IList diagnosticMessages) at
Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureStartup() at
Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureApplicationServices()
at Microsoft.AspNet.Hosting.Internal.HostingEngine.BuildApplication()
原来我必须按照here的说明指定web命令的配置文件或内联参数.按照建议后,我尝试运行应用程序,这次我开始收到以下错误
System.IO.FileNotFoundException Could not load file or assembly
‘Bootstrapper’ or one of its dependencies. The system cannot find the
file specified. at
System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName,String
codeBase,Evidence assemblySecurity,RuntimeAssembly locationHint,
StackCrawlMark& stackMark,IntPtr pPrivHostBinder,Boolean
throwOnFileNotFound,Boolean forIntrospection,Boolean
suppressSecurityChecks) at
System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName,Boolean
suppressSecurityChecks) at
System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName
assemblyRef,RuntimeAssembly reqAssembly,Boolean
suppressSecurityChecks) at
System.Reflection.Assembly.Load(AssemblyName assemblyRef) at
Microsoft.AspNet.Hosting.Startup.StartupLoader.FindStartupType(String
startupAssemblyName,IList diagnosticMessages) at
Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureStartup() at
Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureApplicationServices()
at Microsoft.AspNet.Hosting.Internal.HostingEngine.BuildApplication()
solution要求我在MVC项目中添加对Bootstrapper项目的引用并且它可以工作.但是,它首先打破了单独的Bootstrapper程序集的目的.
问题是,为什么它无法像在Beta7中那样找到Bootstrapper程序集,使用global.json中“projects”下指定的源,或者是忽略global.json的新托管模型?有没有办法指定启动程序集的位置?
更新1
只是想强调一下,在Beta7中,对于Microsoft.AspNet.Server.WebListener和Microsoft.AspNet.Server.Kestrel,它也可以使用“dnx命令”.
"commands": {
"kestrel": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5004 --config wwwroot/Microsoft.AspNet.Hosting.ini","web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5004 --config wwwroot/Microsoft.AspNet.Hosting.ini"
}
但是,对于Beta8中的两个服务器,dnx命令(使用Microsoft.AspNet.Hosting.json文件)都会失败.如果有人想知道它与Beta7中的IIS Helios组件有关,那就不是这样了.令我感到困惑的是为什么程序集查找在Beta8中停止工作
更新2
这是我尝试使用IISExpress在Beta8中运行时获得的堆栈跟踪.看起来它正试图在dnx bin文件夹中找到程序集.
System.IO.FileNotFoundException: Could not load file or assembly
‘Bootstrapper’ or one of its dependencies. The system cannot find the
file specified. File name: ‘Bootstrapper’ at
System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName,IList`1 diagnosticMessages) at
Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureStartup() at
Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureApplicationServices()
at Microsoft.AspNet.Hosting.Internal.HostingEngine.BuildApplication()
=== Pre-bind state information === LOG: DisplayName = Bootstrapper (Partial) WRN: Partial binding information was supplied for an
assembly: WRN: Assembly Name: Bootstrapper | Domain ID: 1 WRN: A
partial bind occurs when only part of the assembly display name is
provided. WRN: This might result in the binder loading an incorrect
assembly. WRN: It is recommended to provide a fully specified textual
identity for the assembly,WRN: that consists of the simple name,
version,culture,and public key token. WRN: See whitepaper
07003 for more information and
common solutions to this issue. LOG: Appbase =
file:///C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/
LOG: Initial PrivatePath = NULL Calling assembly : (Unknown).
=== LOG: This bind starts in default load context. LOG: No application configuration file found. LOG: Using host configuration file: LOG:
Using machine configuration file from
C:WindowsMicrosoft.NETFrameworkv4.0.30319configmachine.config.
LOG: Policy not being applied to reference at this time (private,
custom,partial,or location-based assembly bind). LOG: Attempting
download of new URL
file:///C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/Bootstrapper.DLL.
LOG: Attempting download of new URL
file:///C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/Bootstrapper/Bootstrapper.DLL.
LOG: Attempting download of new URL
file:///C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/Bootstrapper.EXE.
LOG: Attempting download of new URL
file:///C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/Bootstrapper/Bootstrapper.EXE.
也许,如果我运行dnu发布并在IIS下托管它可以工作,但这意味着我每次进行更改时都必须发布它