Не удается решить проблему ссылки на сборку без 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. Здесь он имеет то же самое значение. Когда вы используете что-то из "фреймворка", его нужно указать вframeworkAssemblies
vs является зависимостью пакета nuget.сейчас на особенности:
при использовании библиотеки на основе PCL или .NET Core в .NET Framework ссылки относятся к ссылочным сборкам (иногда называемым сборками контрактов). Некоторые примеры таких вещей, как
System.Runtime
,System.Threading
etc. При использовании проектов на основе 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"
.