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

时间:2015-10-20 15:15:29

标签: asp.net-core asp.net-core-mvc

我正在使用Asp.Net 5和MVC6在洋葱架构(OA)之后的电子商务网站上工作,这样我们就可以在层之间进行松散耦合。我还想在自己的程序集中解耦启动代码,而不是将它放在MVC项目中。

在beta7中按照here的说明,将Startup.cs移动到类库(Bootstrapper)非常容易。使用上述方法的一个有趣的事实是我没有必要从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","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 A.   类型名为' StartupDevelopment'或者' Startup'无法找到   汇编' EcommerceMvcApp'。在   Microsoft.AspNet.Hosting.Startup.StartupLoader.FindStartupType(字符串   startupAssemblyName,IList diagnosticMessages)at   Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureStartup()at   Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureApplicationServices()   在Microsoft.AspNet.Hosting.Internal.HostingEngine.BuildApplication()

原来我必须按照here的说明指定web命令的配置文件或内联参数。按照建议后,我尝试运行应用程序,这次我开始收到错误

  

System.IO.FileNotFoundException无法加载文件或程序集   '引导程序'或其中一个依赖项。系统找不到了   文件指定。在   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,Evidence assemblySecurity,RuntimeAssembly locationHint,   StackCrawlMark&安培; 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)at   System.Reflection.Assembly.Load(AssemblyName assemblyRef)at   Microsoft.AspNet.Hosting.Startup.StartupLoader.FindStartupType(字符串   startupAssemblyName,IList diagnosticMessages)at   Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureStartup()at   Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureApplicationServices()   在Microsoft.AspNet.Hosting.Internal.HostingEngine.BuildApplication()

solution要求我在MVC项目中添加对Bootstrapper项目的引用并且它有效。但是,它首先打破了单独的Bootstrapper程序集的目的。

问题是,为什么它无法像在Beta7中那样找到Bootstrapper程序集,使用" projects"中指定的来源。在global.json中还是忽略global.json的新托管模型?有没有办法指定启动程序集的位置?

更新1

只想突出显示在Beta7中,它也可以使用" dnx命令"适用于Microsoft.AspNet.Server.WebListener和Microsoft.AspNet.Server.Kestrel。

"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:无法加载文件或程序集   '引导程序'或其中一个依赖项。系统找不到了   文件指定。文件名:' Bootstrapper'在   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,Evidence assemblySecurity,RuntimeAssembly locationHint,   StackCrawlMark&安培; 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)at   System.Reflection.Assembly.Load(AssemblyName assemblyRef)at   Microsoft.AspNet.Hosting.Startup.StartupLoader.FindStartupType(字符串   startupAssemblyName,IList`1 diagnosticMessages)at   Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureStartup()at   Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureApplicationServices()   在Microsoft.AspNet.Hosting.Internal.HostingEngine.BuildApplication()

     

===预绑定状态信息===日志:DisplayName = Bootstrapper(部分)WRN:提供了部分绑定信息   程序集:WRN:程序集名称:Bootstrapper |域ID:1 WRN:A   仅部分程序集显示名称为时发生部分绑定   提供。警告:这可能导致活页夹加载不正确   部件。警告:建议提供完全指定的文本   程序集的身份,WRN:由简单名称组成,   版本,文化和公钥令牌。警告:见白皮书   http://go.microsoft.com/fwlink/?LinkId=109270了解更多信息和   这个问题的常见解决方案。日志:Appbase =   文件:/// C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/   日志:初始PrivatePath = NULL调用程序集:(未知)。   ===日志:此绑定在默认加载上下文中启动。日志:找不到应用程序配置文件。日志:使用主机配置文件:LOG:   使用来自的机器配置文件   C:\ WINDOWS \ Microsoft.NET \框架\ v4.0.30319 \ CONFIG \ machine.config中。   日志:此时政策未适用于参考(私人,   自定义,部分或基于位置的程序集绑定)。日志:正在尝试   下载新的URL   文件:/// C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/Bootstrapper.DLL。   日志:尝试下载新网址   文件:/// C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/Bootstrapper/Bootstrapper.DLL。   日志:尝试下载新网址   文件:/// C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/Bootstrapper.EXE。   日志:尝试下载新网址   文件:/// C:/Users/sshassan/.dnx/runtimes/dnx-clr-win-x86.1.0.0-beta8/bin/Bootstrapper/Bootstrapper.EXE

也许,如果我运行dnu发布并在IIS下托管它将会起作用,但这意味着我每次进行更改时都必须发布它

2 个答案:

答案 0 :(得分:1)

我遇到了类似的问题。看起来我们不想从UI层到Infraestructure层进行引用(我们非常严格),甚至不能进行依赖性解析。

也许有可能通过使用后期绑定(我刚刚听说过它),但我认为你应该阅读this article。它基本上说组合根不可重用,每个应用程序应该有一个(即一个用于UI.Web,另一个用于UI.Console,等等)。

这也回答了我关于在UI.Web中有什么DI分辨率的问题,但是需要另一个用户界面,让我们说控制台(答案:它最好在控制台中制作一个DI分辨率,并且< strong>它拥有与控制台应用程序实际工作方式相关的解决方案依赖性。

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

答案 1 :(得分:0)

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

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

另见this issue