Не удается решить проблему ссылки на сборку без frameworkAssemblies
я пытаюсь проверить, что Протокол Буферы будет работать с новыми портативными средами выполнения от ASP.NET команда и в идеале большинство других современных сред. Сборка 3.0.0-alpha4 была создана некоторое время назад с использованием profile259, поэтому я ожидал бы, что в некоторых случаях потребуются некоторые изменения, но я подумал, что попробую. Я в курсе сообщение Орена Новотны о таргетинге .NET Core, и ожидается, что придется внести некоторые изменения в Google.Файл nuspec Protobuf, но ошибка, с которой я сталкиваюсь, ставит меня в тупик.
версия DNX: 1.0.0-rc1-update1
сценарий, который я сейчас пытаюсь протестировать, - это консольное приложение, предназначенное для dnx451. У меня есть очень простой пример приложения:
using Google.Protobuf.WellKnownTypes;
using System;
public class Program
{
public static void Main(string[] args)
{
Duration duration = new Duration { Seconds = 100, Nanos = 5555 };
Console.WriteLine(duration);
}
}
... и маленький project.json:
{
"compilationOptions": { "emitEntryPoint": true },
"dependencies": { "Google.Protobuf": "3.0.0-alpha4" },
"frameworks": {
"dnx451": { }
}
}
обратите внимание, что я даже не используя dnxcore* вот-по иронии судьбы, я получил это работать без проблем.
dnu restore работает отлично;dnx run выдает:
ошибка: c:UsersJonTestProjectsprotobuf-coreclrsrcProtobufTestProgram.cs (9,9): DNX,Version=v4.5.1 ошибка CS0012: тип 'Object' определен в сборке, на которую нет ссылки. Необходимо добавить ссылку на систему сборки.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
следующие изменения приводят к той же ошибке:
- явное добавление a зависимость от
"System.Runtime": "4.0.0"на в рамках - явное добавление зависимости к
"System.Runtime": "4.0.0-beta-23109"наdependenciesРаздел для фреймворка, а также для4.0.10-beta-*,4.0.20-beta-*и4.0.21-beta*. - добавление зависимостей к
System.Runtimeв пакете NuGet (локально) и перестроение против этого -project.lock.jsonбыл обновлен, чтобы включить систему.Время выполнения v4.0. 0, но произошла та же ошибка - то же самое, включая A в пакете, как а также зависимости
шаги сделал работа (самостоятельно, а не dependencies записи), но меня смущают:
- изменение
Console.WriteLineназывать простоConsole.WriteLine("foo")(но никаких других изменений) - изменение типа
durationпеременнаяobjectвместоDuration - удаление всех подсказок буферов протокола полностью, а вместо этого с помощью
TimeSpanили подобное -
добавить следующий проект.json в :
"frameworkAssemblies": { "System.Runtime": "" }
в конечном счете, я не хочу, чтобы пользователи делали это - по крайней мере, не ради буферов протокола. Я предполагаю, что это что-то чтобы сделать с тем, как мы строим буферы протокола, но поскольку я не понимаю причину правильно, это трудно исправить.
я полагаю, что если бы я мог найти способ сделать dependencies запись работы, я мог бы добавить эту зависимость в Протокол буферизует себя, что было бы хорошо, но как имеющее зависимость от системы.Время выполнения v4.0.0 в проекте.файл блокировки, похоже, не помогает, я должен что-то упустить :(
3 ответа:
так что если вы прищуритесь и посмотрите на проект.json, это в основном nuspec с небольшим количеством goop, чтобы описать, какие параметры компиляции и источники необходимы для создания проекта. У Nuspecs сегодня есть 2 раздела,
frameworkAssembliesдля "встроенных" вещей иdependenciesдля других зависимостей nuget. Здесь он имеет то же самое значение. Когда вы используете что-то из "фреймворка", его нужно указать вframeworkAssembliesvs является зависимостью пакета nuget.сейчас на особенности:
при использовании библиотеки на основе PCL или .NET Core в .NET Framework ссылки относятся к ссылочным сборкам (иногда называемым сборками контрактов). Некоторые примеры таких вещей, как
System.Runtime,System.Threadingetc. При использовании проектов на основе MSBUILD, есть задача, которая выполняется, которая в основном автоматически добавляет все наSystem.*ссылки на компилятор C#, чтобы избежать этого беспорядка. Эти сборки называются фасадами в .NET Framework. Неудачник часть в том, что он добавляет все из них, даже если они не используются. Зависимость отSystem.Runtimeявляется триггером для этого поведения (при запуске на основе csproj файлов .NET Framework).причина, по которой добавление ссылки на один и тот же пакет не работает, заключается в том, что папка .NET Framework (net4*) для этих сборок контрактов (например, System.Runtime), в них нет библиотек DLL. Если вы посмотрите на эти папки, вы увидите пустой . Причина этого заключается в том, что когда вы объявляете пакет nuget с
frameworkAssemblyссылкаSystem.Runtime, системы проекта msbuild не удается установить его (очень сложная ошибка и проблема проектирования).это, вероятно, сделало вещи более размытыми...
Я принял ответ Дэвида Фаулера причиной почему все это произошло. Теперь с точки зрения того, что я должен do об этом, похоже, мне нужно добавить
frameworkAssembliesэлемент в файле nuspec дляGoogle.Protobuf:<package> <metadata> ... <frameworkAssemblies> <frameworkAssembly assemblyName="System.Runtime" targetFramework="net45" /> </frameworkAssemblies> </metadata> ... </package>Это
frameworkAssemblyссылка затем заканчивается вproject.lock.jsonв клиентском проекте, и все хорошо.однако, судя по другому комментарию Дэвида ("мы собираемся посмотреть на исправление этого"), мне может не понадобиться делать все равно...
мне кажется, что ваша проблема существует только потому, что вы выбрали консольное приложение вместо "ASP.NET веб-приложение" / "ASP.NET 5 шаблонов" / "пусто". Я сделал простой тест использования пустой шаблон, добавили
"Google.Protobuf": "3.0.0-alpha4"от NuGet и, наконец, просто измененStartup.csтак что он используетGoogle.Protobuf.WellKnownTypes:
- добавил
using Google.Protobuf.WellKnownTypes;- добавил
var duration = new Duration { Seconds = 100, Nanos = 5555 };внутриConfigure- изменен
await context.Response.WriteAsync("Hallo World!");доawait context.Response.WriteAsync(duration.ToString());финальный код из
Startup.cs:using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft.Extensions.DependencyInjection; using Google.Protobuf.WellKnownTypes; namespace ProtobufTest { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); var duration = new Duration { Seconds = 100, Nanos = 5555 }; app.Run(async context => { await context.Response.WriteAsync(duration.ToString()); }); } // Entry point for the application. public static void Main(string[] args) => WebApplication.Run<Startup>(args); } }результат ASP.NET 5 приложение отображается успешно
100.5555sв веб-браузере.вы можете скачать демо-проект из здесь.
обновление: я проанализировал проблему с чистым консольным приложением DNX, которое использует код и может найти причину проблема
duration.ToString()метод, который работает внутри ASP.NET среда, но не в чистом консольном приложении. Этот причина проблемы интересна, и я пытаюсь исследовать, но я хотел бы поделиться своими текущими результатами с другимия мог бы сделать работу следующий код:
using Google.Protobuf.WellKnownTypes; using System; namespace ConsoleApp3 { public class Program { public static void Main(string[] args) { var duration = new Duration { Seconds = 100, Nanos = 5555 }; Console.WriteLine("{0}.{1:D4}s", duration.Seconds, duration.Nanos); } } }можно скачать рабочий проект от здесь.
я прокомментировал дополнительно строку
//[assembly: Guid("b31eb124-49f7-40bd-b39f-38db8f45def3")]на
AssemblyInfo.csчтобы не было ненужной ссылки на"Microsoft.CSharp", которые имеют много других ссылок. Элементproject.jsonсодержится в демонстрационный проект:{ ... "dependencies": { "Google.Protobuf": "3.0.0-alpha4" }, "frameworks": { "dnx451": { }, "dnxcore50": { "dependencies": { "System.Console": "4.0.0-beta-23516" } } } }кстати, в том числе
"System.Console": "4.0.0-beta-23516"на"dnxcore50"часть"frameworks"не требуется, посколькуConsoleпространство имен (дляConsole.WriteLine) существуют вmscorlibнаDNX 4.5.1. Если бы кто-то попытался добавить"System.Console": "4.0.0-beta-23516"на уровне common зависимости один получить ошибку с начинается с текстаошибка CS0433 тип "консоль" существует в обеих системах.Приставка, Версия=4.0.0.0, культуры=нейтральный, значения PublicKeyToken=b03f5f7f11d50a3a и 'mscorlib, Version=4.0.0.0, Culture=нейтральный, ConsoleApp3 значения PublicKeyToken=b77a5c561934e089'.DNX 4.5.1
обновлено 2: можно заменить строку
Console.WriteLine("{0}.{1:D4}s", duration.Seconds, duration.Nanos);до
Console.WriteLine((object)duration);чтобы заставить его работать. Просто использование
Console.WriteLine(duration);илиvar str = duration.ToString();выдает ошибку, которую вы описали.обновлено 3: я проверил, что код
duration.ToString()звонки строки что использовать в линии для форматирования. Кажется, что кодduration.ToString()делает действительно то же самое, что((object)duration).ToString()наWellKnownTypesтипы (например,Duration).последнее замечание, которое я считаю важным. Описанная проблема существует только для dnx451 (или dnx452 или dnx46). Если бы можно было удалить строки
"dnx451": { },с
"frameworks"частьproject.jsonтогда программа будет компилироваться только для DNX Core 5.0 ("dnxcore50"). Можно легко проверить, что у вас не будет никаких проблем больше.обновлено 4: наконец-то я нашел очень простое решение проблемы: нужно просто добавить
"Microsoft.AspNet.Hosting": "1.0.0-rc1-final"зависимость от проекта:{ "dependencies": { "Google.Protobuf": "3.0.0-alpha4", "Microsoft.AspNet.Hosting": "1.0.0-rc1-final" } }это следует для загрузки многих ненужных DLL, но теперь зависимости будут правильно решены.
окончательный проект может быть скомпилирован без каких-либо проблем для dnx451 и dnxcore50. Я интерпретирую результаты следующим образом: "Google.Protobuf" работают с обоими dnx451 и dnxcore50, но автоматическое разрешение зависимостей RC1 по-прежнему глючит, и он не может правильно решить некоторые необходимые зависимости "Google.Protobuf".
причины добавления непосредственно ненужные
"Microsoft.AspNet.Hosting": "1.0.0-rc1-final"ссылка может рассматриваться только как временное решение. Я думаю, что разрешение зависимостей используется в ASP.NET 5 и DNX все еще глючит. Я написал некоторое время до вопрос, который все еще открыт. Проблема дает пример, когда решение прямой включенная зависимость может обеспечить другое результаты в виде зависимостей решаетсяdnu restore. Именно по этой причине я начал сравнивать зависимость код, который я отправил вам изначально с зависимостями неработающего проекта. После некоторых тестов я нашел обходной путь и уменьшил его до единственной зависимости:"Microsoft.AspNet.Hosting": "1.0.0-rc1-final".