目前在学习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的更多相关文章

  1. .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'问题: ...

  2. eclipse中的js文件报错的解决办法

    在使用别人的项目的时候,导入到eclipse中发现js文件报错,解决办法是关闭eclipse的js校验功能. 三个步骤: 1. 右键点击项目->properties->Validation ...

  3. 关于pycharm中安装第三方库时报错的解决办法(一)

    记录自己的生活!   一.事发背景 在pycharm中直接安装第三方库时因为版本问题总是无法安装成功,事情不大,但是很重要.   二.经过 最开始我自己电脑上安装了Python3.6和Python2. ...

  4. vue-cli创建的项目中引入第三方库报错 'caller', 'calle', and 'arguments' properties may not be...

    http://blog.csdn.net/sophie_u/article/details/76223978 以在vue中引入mui第三方库为例: 虽然针对vue,有单独的vue-mui库可以使用,但 ...

  5. 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时,报错. 如上,单 ...

  6. 【转】】Vue项目部署tomcat,刷新报错404解决办法

    转自[https://blog.csdn.net/g631521612/article/details/82835518] 解决方式: - 在tocmat的webapps下的项目中创建WEB-INF文 ...

  7. Eclipse安卓项目导入android.support.design报错的解决办法

    导入android.support.design出错:1.项目除了需要依赖appcompat_v7包外还要design包2.design包就是在安卓sdk下Extras中的android.suppor ...

  8. ASP.NET MVC 返回JsonResult序列化内容超出最大限制报错的解决办法

    在使用MVC的时候我们经常会在Controller的Action方法中返回JsonResult对象,但是有时候你如果序列化的对象太大会导致JsonResult从Controller的Action返回后 ...

  9. PyCharm注释中出现中文运行报错的解决办法

    SyntaxError: Non-UTF-8 code starting with '..... 方法一:在文件首行加上 # -*- coding:utf-8 -*- 方法二:更改编码格式 File ...

随机推荐

  1. PredictionIO+Universal Recommender快速开发部署推荐引擎的问题总结(2)

    1, 对Universal Recommender进行pio build成功,但是却提示No engine found Building and delpoying model [INFO] [Eng ...

  2. Prism for WPF再探(基于Prism事件的模块间通信)

    上篇博文链接 Prism for WPF初探(构建简单的模块化开发框架) 一.简单介绍: 在上一篇博文中初步搭建了Prism框架的各个模块,但那只是搭建了一个空壳,里面的内容基本是空的,在这一篇我将实 ...

  3. 关于a标签颜色的探索

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Golang 网络爬虫框架gocolly/colly 三

    Golang 网络爬虫框架gocolly/colly 三 熟悉了<Golang 网络爬虫框架gocolly/colly一>和<Golang 网络爬虫框架gocolly/colly二& ...

  5. 微信小程序参数二维码6问6答

    微信小程序参数二维码[基础知识篇],从6个常见问题了解小程序参数二维码的入门知识. 1.什么是小程序参数码? 微信小程序参数二维码:针对小程序特定页面,设定相应参数值,用户扫描后进入相应的页面. 2. ...

  6. pagelatch等待在tempdb的gsm页面上

    Each data file has a gam page, sql will update it when allocate space in the file. Will see contenti ...

  7. jQuery 属性(十二)

    属性 描述 context 在版本 1.10 中被弃用.包含传递给 jQuery() 的原始上下文. jquery 包含 jQuery 版本号. jQuery.fx.interval 改变以毫秒计的动 ...

  8. Java第一章----Java概述+环境搭建

    写在前面的话: Java基础的东西看过好几遍,但是过一段都就忘记了,所以这次我决定花费一些时间整理一个系列博客供以后方便查阅.此系列根据Java编程思想+Java核心技术两本书整理而来,这两本书也是我 ...

  9. 固定表头,单元格td宽度自适应,多内容出现-横向纵向滚动条数据表格的<前世今生>

    固定表头,单元格td宽度自适应,多内容出现-横向纵向滚动条数据表格的<前世今生>     先上图例   & 无论多少数据--都完美! 背景:由于我司行业方向,需要很多数据报表,则t ...

  10. Loadrunner11.0调用Jar包

    又好几天不写东西了,是不是意味着最近没有大的进步,时时敲打自己. 今天把loadrunner如何调用Jar包搞定了,现在把配置的过程中需要注意的东西写下来,分享给小伙伴儿,减少他们在前行路上的弯路. ...