我正在使用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项目将引用所有其他项目,如基础设施,服务等,以便连接依赖注入 .
在Onion Architecture规则之后,不在MVC项目中引用Bootstrapper项目的原因是为了避免直接从MVC项目访问Infrastructure代码 . 所以这一切都正常,直到我今天早上升级到Beta8 .
随着托管模型从IIS更改为Kestrel,我不得不重构global.json和project.json文件,如下所示
global.json
{
"projects": [ "Source/Projects","Source/Bootstrapper" ],
"sdk": {
"architecture": "x64",
"runtime": "clr",
"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运行,我都开始收到以下错误
内部服务器错误System.InvalidOperationException在程序集“EcommerceMvcApp”中找不到名为“StartupDevelopment”或“Startup”的类型 . 位于Microsoft的Microsoft.AspNet.Hosting.Hosting.Ensure应用程序服AspNet.Hosting.Internal.HostingEngine.BuildApplication()
原来我必须指定web命令的配置文件或内联参数,如here所述 . 按照建议后,我尝试运行该应用程序,这次我开始收到以下错误
System.IO.FileNotFoundException无法加载文件或程序集“Bootstrapper”或其依赖项之一 . 该系统找不到指定的文件 . 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,String codeBase) ,证据assemblySecurity,RunCAslmbly locationHint,StackPrawlMark&stackMark,IntPtr pPrivHostBinder,Boolean throwOnFileNotFound,Boolean forIntrospection,Boolean suppressSecurityChecks)at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef,Evidence assemblySecurity,RuntimeAssembly reqAssembly,StackCrawlMark&stackMark,IntPtr pPrivHostBinder,Boolean throwOnFileNotFound,Boolean forIntrospection,Boolean suppressSecurityChecks)在System.Reflection.Assembly.Load(AssemblyName assemblyRef)上的Microsoft.AspNet.Hosting.Startup.StartupLoader.FindStartupType(String startupAssemblyName,IList) diagnosticMessages)位于Microsoft.AspNet.Hosting.HostingEngine.Ensure.Eosure.Eosure.Eosure.Einsure.Ensure.Eosure.Exture应用程序中的Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureApplicationServices()上的Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureStartup()
solution要求我在MVC项目中添加对Bootstrapper项目的引用,它可以工作 . 但是,它首先打破了单独的Bootstrapper程序集的目的 .
问题是,为什么它无法像在Beta7中那样找到Bootstrapper程序集,使用global.json中“projects”下指定的源,或者是忽略global.json的新托管模型?有没有办法指定启动程序集的位置?
Update 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中停止工作
Update 2
这是我尝试使用IISExpress在Beta8中运行时获得的堆栈跟踪 . 看起来它正试图在dnx bin文件夹中找到程序集 .
System.IO.FileNotFoundException:无法加载文件或程序集“Bootstrapper”或其依赖项之一 . 该系统找不到指定的文件 . 文件名:System.Reflection.RuntimeAssembly._nLoad中的'Bootstrapper'(AssemblyName fileName,String codeBase,Evidence assemblySecurity,System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName,String codeBase,Evidence assemblySecurity,RuntimeAssembly locationHint,StackCrawlMark&stackMark,IntPtr pPrivHostBinder,Boolean throwOnFileNotFound,Boolean forIntrospection的RuntimeAssembly locationHint,StackCrawlMark&stackMark,IntPtr pPrivHostBinder,Boolean forIntrospection,Boolean suppressSecurityChecks) ,在System.Reflection.Assembly.Load(AssemblyName assemblyRef)处的System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef,Evidence assemblySecurity,RuntimeAssembly reqAssembly,StackCrawlMark&stackMark,IntPtr pPrivHostBinder,Boolean throwOnFileNotFound,Boolean forIntrospection,Boolean suppressSecurityChecks)处的布尔值suppressSecurityChecks)位于Microsoft.AspNet.Ho的Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureStartup()中的Microsoft.AspNet.Hosting.Startup.StartupLoader.FindStartupType(String startupAssemblyName,IList`1 diagnosticMessages) Microsoft.AspNet.Hosting.Internal.HostingEngine.BuildApplication()中的sting.Internal.HostingEngine.EnsureApplicationServices()===预绑定状态信息===日志:DisplayName = Bootstrapper(部分)WRN:提供了部分绑定信息程序集:WRN:程序集名称:Bootstrapper |域ID:1 WRN:仅提供部分程序集显示名称时发生部分绑定 . 警告:这可能导致 Binders 加载错误的程序集 . 警告:建议为程序集提供完全指定的文本标识,WRN:由简单名称,版本,区域性和公钥标记组成 . 警告:有关此问题的更多信息和常见解决方案,请参阅白皮书http://go.microsoft.com/fwlink/?LinkId=109270 . 日志:Appbase = file:/// C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/日志:初始PrivatePath = NULL调用程序集:(未知) . ===日志:此绑定在默认加载上下文中启动 . 日志:找不到应用程序配置文件 . 日志:使用主机配置文件:日志:使用C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ config \ machine.config中的计算机配置文件 . 日志:此时策略未应用于引用(私有,自定义,部分或基于位置的程序集绑定) . 日志:尝试下载新的URL文件:/// C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/Bootstrapper.DLL . 日志:尝试下载新的URL文件:/// C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/Bootstrapper/Bootstrapper.DLL . 日志:尝试下载新的URL文件:/// C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/Bootstrapper.EXE . 日志:尝试下载新的URL文件:/// C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/Bootstrapper/Bootstrapper.EXE .
也许,如果我运行dnu发布并在IIS下托管它可以工作,但这意味着我每次进行更改时都必须发布它
2 回答
我遇到了类似的问题 . 看起来我们不想从UI层到Infraestructure层进行引用(我们非常严格),甚至不需要进行依赖项解析 .
也许有可能通过使用 late binding (我刚刚听说过它),但我认为你应该阅读this article . 它基本上说组合根不可重复使用,每个应用程序应该有一个(即一个用于UI.Web,另一个用于UI.Console,依此类推) .
这也回答了我关于在UI.Web中有什么DI分辨率的问题,但是需要另一个UI,让's say Console (answer: it'更适合在Console中制作一个DI分辨率,并且 it'll have it's own resolution dependences related to how a Console Application actually works ) .
我希望能帮助你澄清这个问题 .
托管配置文件格式从INI更改为Json . 试试这个:
另见this issue .