分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 网页技术

ASP.NET CORE MVC 2.0 项目中引用第三方DLL报错的解决办法 - InvalidOperationException: Cannot find compilation library location for package

发布时间:2023-09-06 01:31责任编辑:傅花花关键词:.NETMVC

目前在学习ASP.NET CORE MVC中,今天看到微软在ASP.NET CORE MVC 2.0中又恢复了允许开发人员引用第三方DLL程序集的功能,感到甚是高兴!于是我急忙写了个Demo想试试,我的项目结构如下:

可以看到解决方案中就两个项目,AspNetCoreWebApp就是一个ASP.NET CORE MVC 2.0的项目,而MyNetCoreLib是一个.Net Core 2.0的类库项目,为了体现AspNetCoreWebApp是通过程序集来引用MyNetCoreLib的,我还在解决方案中创建了一个文件夹叫Reference,将类库项目MyNetCoreLib编译后生成的DLL文件放到了Reference文件夹中,然后再AspNetCoreWebApp中通过添加引用程序集的方式引用了MyNetCoreLib.dll,如下图所示:

然后编译整个解决方案,调试AspNetCoreWebApp这个项目,运行立马报错。。。错误如下:

这明显是一个运行时错误,因我在编译整个解决方案的时候是成功的,没有报任何错误。后来去网上查了查资料,发现虽然我们在项目AspNetCoreWebApp中引用了MyNetCoreLib.dll,而且项目AspNetCoreWebApp编译后也在其Bin目录下输出了MyNetCoreLib.dll这个文件,如下图所示:

但是ASP.NET CORE MVC的依赖注入环境其实并不知道该到哪里去找MyNetCoreLib.dll这个文件,所以才会在运行时报出InvalidOperationException: Cannot find compilation library location for package ‘MyNetCoreLib‘这种错误。。。开发人员需要用代码去告诉ASP.NET CORE MVC应该到哪里去找到MyNetCoreLib.dll这个文件。

因此首先我们需要定义一个叫MetadataReferenceFeatureProvider的类,代码如下,其关键代码就是告诉ASP.NET CORE MVC的依赖注入环境去AppDomain.CurrentDomain.BaseDirectory(也就是Bin目录)下找我们在项目中引用的程序集文件

using Microsoft.AspNetCore.Mvc.ApplicationParts;using Microsoft.AspNetCore.Mvc.Razor.Compilation;using Microsoft.CodeAnalysis;using Microsoft.Extensions.DependencyModel;using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Reflection.PortableExecutable;using System.Threading.Tasks;namespace AspNetCoreWebApp.Utils{ ???public class ReferencesMetadataReferenceFeatureProvider : IApplicationFeatureProvider<MetadataReferenceFeature> ???{ ???????public void PopulateFeature(IEnumerable<ApplicationPart> parts, MetadataReferenceFeature feature) ???????{ ???????????var libraryPaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase); ???????????foreach (var assemblyPart in parts.OfType<AssemblyPart>()) ???????????{ ???????????????var dependencyContext = DependencyContext.Load(assemblyPart.Assembly); ???????????????if (dependencyContext != null) ???????????????{ ???????????????????foreach (var library in dependencyContext.CompileLibraries) ???????????????????{ ???????????????????????if (string.Equals("reference", library.Type, StringComparison.OrdinalIgnoreCase)) ???????????????????????{ ???????????????????????????foreach (var libraryAssembly in library.Assemblies) ???????????????????????????{ ???????????????????????????????//告诉ASP.NET CORE MVC如果现在项目中有引用第三方程序集,要到AppDomain.CurrentDomain.BaseDirectory这个文件夹(就是Bin目录)下去寻找该程序集的dll文件 ???????????????????????????????libraryPaths.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, libraryAssembly)); ???????????????????????????} ???????????????????????} ???????????????????????else ???????????????????????{ ???????????????????????????foreach (var path in library.ResolveReferencePaths()) ???????????????????????????{ ???????????????????????????????libraryPaths.Add(path); ???????????????????????????} ???????????????????????} ???????????????????} ???????????????} ???????????????else ???????????????{ ???????????????????libraryPaths.Add(assemblyPart.Assembly.Location); ???????????????} ???????????} ???????????foreach (var path in libraryPaths) ???????????{ ???????????????feature.MetadataReferences.Add(CreateMetadataReference(path)); ???????????} ???????} ???????private static MetadataReference CreateMetadataReference(string path) ???????{ ???????????using (var stream = File.OpenRead(path)) ???????????{ ???????????????var moduleMetadata = ModuleMetadata.CreateFromStream(stream, PEStreamOptions.PrefetchMetadata); ???????????????var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata); ???????????????return assemblyMetadata.GetReference(filePath: path); ???????????} ???????} ???}}

其次我们还要在项目AspNetCoreWebApp的Startup.cs文件中的services.AddMvc()方法上注册我们定义的这个Provider,代码如下(注意ConfigureServices方法中的代码):

using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Hosting;using Microsoft.Extensions.Configuration;using Microsoft.Extensions.DependencyInjection;using Microsoft.AspNetCore.Mvc.Razor.Compilation;using AspNetCoreWebApp.Utils;namespace AspNetCoreWebApp{ ???public class Startup ???{ ???????public Startup(IConfiguration configuration) ???????{ ???????????Configuration = configuration; ???????} ???????public IConfiguration Configuration { get; } ???????// This method gets called by the runtime. Use this method to add services to the container. ???????public void ConfigureServices(IServiceCollection services) ???????{ ???????????services.AddMvc().ConfigureApplicationPartManager(manager => ???????????{ ???????????????//移除ASP.NET CORE MVC管理器中默认内置的MetadataReferenceFeatureProvider,该Provider如果不移除,还是会引发InvalidOperationException: Cannot find compilation library location for package ‘MyNetCoreLib‘这个错误 ???????????????manager.FeatureProviders.Remove(manager.FeatureProviders.First(f => f is MetadataReferenceFeatureProvider)); ???????????????//注册我们定义的ReferencesMetadataReferenceFeatureProvider到ASP.NET CORE MVC管理器来代替上面移除的MetadataReferenceFeatureProvider ???????????????manager.FeatureProviders.Add(new ReferencesMetadataReferenceFeatureProvider()); ???????????}); ???????} ???????// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. ???????public void Configure(IApplicationBuilder app, IHostingEnvironment env) ???????{ ???????????if (env.IsDevelopment()) ???????????{ ???????????????app.UseDeveloperExceptionPage(); ???????????????app.UseBrowserLink(); ???????????} ???????????else ???????????{ ???????????????app.UseExceptionHandler("/Home/Error"); ???????????} ???????????app.UseStaticFiles(); ???????????app.UseMvc(routes => ???????????{ ???????????????routes.MapRoute( ???????????????????name: "default", ???????????????????template: "{controller=Home}/{action=Index}/{id?}"); ???????????}); ???????} ???}}

然后重新编译代码,调试项目AspNetCoreWebApp,好了这下项目成功运行了,没有报任何错误。

也不知道本文讨论的这个问题是ASP.NET CORE MVC 2.0的一个缺陷,会在以后版本中修复,还是微软故意为之?因为我试了下在.NET CORE 2.0的控制台项目中,直接引用第三方程序集DLL文件是完全没问题的,不需要写任何额外的代码就可以使用。既然微软在ASP.NET CORE MVC中也开放了引用第三方程序集这个功能,其实就完全可以把它做的和老.Net Framework一样,自动去Bin目录下面寻找DLL文件即可,希望ASP.NET CORE MVC以后的版本能够完善这个功能,不再需要开发人员在引用DLL文件后,还要添加额外的代码。

ASP.NET CORE MVC 2.0 项目中引用第三方DLL报错的解决办法 - InvalidOperationException: Cannot find compilation library location for package

原文地址:http://www.cnblogs.com/OpenCoder/p/8052693.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved