Этап 1.
Есть проект NetStandardLibrary на NetStandard 2.0. В него подключен в качестве зависимости пакет "System.IO.FileSystem.AccessControl" и объявлен единственный класс с методом Test:
using System;
namespace NetStandardLibrary
{
public class Class1
{
public static bool Test(string folder)
{
try
{
var ds = new System.Security.AccessControl.DirectorySecurity(folder, System.Security.AccessControl.AccessControlSections.All);
return true;
}
catch
{
return false;
}
}
}
}
Компилируем проект, на выходе получаем NetStandardLibrary.dll/NetStandardLibrary.pdb/NetStandardLibrary.deps.json.
Этап 2.
Есть проект TestNetFullApp (консольное приложение). Подключаем в него NetStandardLibrary как простую ссылку из солюшена, код приложения выглядит следующим образом:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestNetFullApp
{
class Program
{
static void Main(string[] args)
{
try
{
var d = NetStandardLibrary.Class1.Test(Environment.CurrentDirectory);
Console.WriteLine("Hello World!");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
}
}
Запускаем и получаем исключение (1). Как видно, среди загруженных сборок (2) не числится System.IO.FileSystem.AccessControl, подключенный в NetStandardLibrary. Собственно, его нет и в выходном каталоге приложения.
Окей. В NetStandardLibrary ставим галку "Создать пакет Nuget при сборке", настраиваем в Visual Studio папку этого проекта как источник пакетов, подключаем пакет в TestNetFullApp. Запускаем - вуаля, ошибки нет, файл появился в выходном каталоге TestNetFullApp, т.к. System.IO.FileSystem.AccessControl была подтянута как зависимость для пакета NetStandardLibrary.
Хорошо, смотрим, что же это за файл. System.IO.FileSystem.AccessControl.dll весит 27.1кб.
Заглядываем в папку локального пользователя, далее ".nuget/packages", куда нынче механизмом PackageReference складируются все скачанные пакеты. Хм, что за диво? Почему библиотека весит 29.1кб?
Ищем в соседних папках и да! Искомый файл обнаруживается в соседней "\lib\net461". Осмотр через ILSpy подтверждает, что это идентичные библиотеки с атрибутами TypeForwardedTo внутри. А вот копия в "\lib\netstandard2.0" этих атрибутов не имеет. Что, собственно, подтверждается экспериментом - если подпихнуть сборку из "\lib\netstandard2.0" приложению TestNetFullApp, то вылетает исключение PlatformNotSupportedException.
Этап 3.
Создаем консольное приложение TestNetCoreApp и подключаем NetStandardLibrary как проект из солюшена.
Запускаем - всё работает. Причем сборка System.IO.FileSystem.AccessControl.dll была подключена из папки ".nuget/packages".
-----------------------------------------------------------------------
В общем, в связи с этим возник ряд вопросов по работе самого механизма подключения зависимостей в NetStandard и .Net Core.
1) Где можно почитать подробно о том, как это работает?
2) Почему приложение TestNetFullApp ссылается на сборку из папки "\lib\net461" вместо "\lib\netstandard2.0"? NetStandard работает как интерфейс и ищет именно сборку на той платформе, на которой запущено приложение?
3) Если ответ на вопрос в предыдущем пункте "да", то как же создать независимую от Nuget сборку под NetStandard со всеми вариантами зависимых сборок (той же System.IO.FileSystem.AccessControl.dll), чтобы оно работало без проблем на NetFramework, NetCore, NetStandard путем просто подключения NetStandardLibrary как reference.
3.1) Уточнение к вопросу. Дело в том, что в одном из проектов формируется сборка, устанавливаемая в GAC, она подключается в Design-time в Visual Studio для работы с Razor. Если переводить её на NetStandard, то возникает необходимость либо иметь все сборки, от которых она зависит, в GAC, либо пользоваться Costura.Fody (включение зависимых сборок в тело основной сборки в виде embedded resources). Второй вариант очень удобен, все зависимости подгружаются автоматом при загрузке основной сборки. Но с NetStandard это не прокатывает - в качестве зависимости цепляется файл из "\lib\netstandard2.0", а приложению нужен не он.
4) Что будет, если я запущу TestNetCoreApp в профиле другого пользователя, у которого нет скачанных пакетов в ".nuget/packages"? Они подтянутся автоматом? Если да, то что должно быть установлено в системе?