首页 文章

在Beta8中Asp.Net 5 MVC 6 Startup.cs程序集解耦

提问于
浏览
5

我正在使用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 回答

  • 0

    我遇到了类似的问题 . 看起来我们不想从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 ) .

    我希望能帮助你澄清这个问题 .

  • 1

    托管配置文件格式从INI更改为Json . 试试这个:

    {  
      "Hosting:Application": "Bootstrapper",
    }
    

    另见this issue .

相关问题