ASP.NET CORE MVC 2.0 项目中引用第三方DLL报错的解决办法 - InvalidOperationException: Cannot find compilation library location for package
目前在学习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的更多相关文章
- .ner core InvalidOperationException: Cannot find compilation library location for package 'xxx' 和 SqlException: 'OFFSET' 附近有语法错误。 在 FETCH 语句中选项 NEXT 的用法无效。问题
原文地址:传送门 1.InvalidOperationException: Cannot find compilation library location for package 'xxx'问题: ...
- eclipse中的js文件报错的解决办法
在使用别人的项目的时候,导入到eclipse中发现js文件报错,解决办法是关闭eclipse的js校验功能. 三个步骤: 1. 右键点击项目->properties->Validation ...
- 关于pycharm中安装第三方库时报错的解决办法(一)
记录自己的生活! 一.事发背景 在pycharm中直接安装第三方库时因为版本问题总是无法安装成功,事情不大,但是很重要. 二.经过 最开始我自己电脑上安装了Python3.6和Python2. ...
- vue-cli创建的项目中引入第三方库报错 'caller', 'calle', and 'arguments' properties may not be...
http://blog.csdn.net/sophie_u/article/details/76223978 以在vue中引入mui第三方库为例: 虽然针对vue,有单独的vue-mui库可以使用,但 ...
- vue-cli创建的项目中引入第三方库报错'caller', 'calle', and 'arguments' properties may not be...
本文链接:https://blog.csdn.net/Sophie_U/article/details/76223978 问题: 在vue的main.js中引入mui.min.js时,报错. 如上,单 ...
- 【转】】Vue项目部署tomcat,刷新报错404解决办法
转自[https://blog.csdn.net/g631521612/article/details/82835518] 解决方式: - 在tocmat的webapps下的项目中创建WEB-INF文 ...
- Eclipse安卓项目导入android.support.design报错的解决办法
导入android.support.design出错:1.项目除了需要依赖appcompat_v7包外还要design包2.design包就是在安卓sdk下Extras中的android.suppor ...
- ASP.NET MVC 返回JsonResult序列化内容超出最大限制报错的解决办法
在使用MVC的时候我们经常会在Controller的Action方法中返回JsonResult对象,但是有时候你如果序列化的对象太大会导致JsonResult从Controller的Action返回后 ...
- PyCharm注释中出现中文运行报错的解决办法
SyntaxError: Non-UTF-8 code starting with '..... 方法一:在文件首行加上 # -*- coding:utf-8 -*- 方法二:更改编码格式 File ...
随机推荐
- java方式连接数据操作数据库
package com.bdqn.dao.impl; import java.io.IOException;import java.io.InputStream;import java.io.Seri ...
- php-redis 操作类 封装
<?php /** * redis操作类 * 说明,任何为false的串,存在redis中都是空串. * 只有在key不存在时,才会返回false. * 这点可用于防止缓存穿透 * */ cla ...
- Linux第五节随笔 /file / vim / suid /sgid sbit
三期第四讲1.查询文件类型与文件位置命令 file 作用:查看文件类型(linux下的文件类型不以后缀名区分) 语法举例: [root@web01 ~]# file passwd passwd: AS ...
- java递归实现文件夹文件的遍历输出
学习java后对一个面试小题(今年年初在团结湖面试的一个题目) 的习题的编写. ''给你一个文件,判断这个文件是否是目录,是目录则输入当前目录文件的个数和路径,''' /** * @author li ...
- SVN添加用户权限
点击properties
- Webpack 2 视频教程 010 - 配置 ESLint 实现代码规范自动测试 (下)
原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...
- centos 命令
1.查看占用端口的进程 netstat -lnp|grep 3000(3000为端口号) Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statis ...
- IIFF(立即执行函数表达式)
立即执行函数表达式(Immediately-invoked function expression,IIFF) 在javascript(ES5)中,是没有块级作用域的概念的 for (var i = ...
- Mac 下 android/iOS https抓包
一.Charles简介 Charles,是用Java开发的,所以跨平台,不仅可以在Mac上使用,Linux以及Window下都是可以使用的,当然需要安装JDK,才能运行,但目前是收费的. 二.下载 官 ...
- spark 1.6 完全分布式平台搭建
软件环境: scala-2.11.4.tgz spark-1.6.2-bin-hadoop2.6.tgz 操作步骤: 一. 安装scala 1. 解压scala (tar –zxvf filena ...