Компиляция консольного приложения.Net Core с CoreRT и Dapper
Я пытаюсь скомпилировать мой код (консольное приложение ядра.net) в собственный.exe для win-x64, используя CoreRT. Я мог следить за документацией вплоть до раздела, касающегося рефлексии и использования файла rd.xml, в котором я сейчас застрял.
Мой проект использует Dapper в качестве ORM, который полагается на отражение, чтобы связать объекты из моей базы данных. У меня есть только 2 разных типа, которые я связываю, поэтому я предполагаю, что мне нужно включить эти типы в rd.xml.
Прямо сейчас, когда я пытаюсь бежать dotnet publish -r win-x64 -c release
из ядра.net cli он успешно завершается, однако во время выполнения мой скомпилированный файл.exe вызывает исключение со следующим фрагментом:
---> (Внутреннее исключение #0) System.TypeInitializationException: инициализатор типа выдал исключение. Чтобы определить, какой тип, проверьте свойство StackTrace InnerException. ---> EETypeRva:0x01202268(System.Reflection.MissingRuntimeArtifactException): этот объект не может быть вызван, поскольку для него разрешен только метаданные: "Dapper.SqlMapper.TypeHandlerCache
.SetHandler (Dapper.SlM) ITypeHandler)'Для получения дополнительной информации, пожалуйста, посетите http://go.microsoft.com/fwlink/?LinkID=616867
Мой файл rd.xml выглядит так:
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<Type Name="Dapper.SqlMapper.TypeHandlerCache{System.Data.DataTable}">
<MethodInstantiation Name="SetHandler" Arguments="Dapper.SqlMapper.ITypeHandler" Dynamic="Required" />
</Type>
</Application>
</Directives>
Я предполагаю, что мне нужно включить ссылки на мои модели здесь, которые будут Foo
а также Bar
, но полученная ошибка относится конкретно к Dapper.
Файл rd.xml находится внутри моего каталога проекта, и на него есть ссылка в MyProject.csproj, например, так:
<ItemGroup>
<EmbeddedResource Include="rd.xml" />
</ItemGroup>
Мне интересно, связана ли эта проблема с моей структурой (возможно, на файл rd.xml следует ссылаться по-другому) или с содержимым моего файла rd.xml. Кто-нибудь имел дело с этим или использовал CoreRT в проекте, который использует Dapper?
2 ответа
Попробуйте добавить это в директивы:
<Assembly Name="System.Data.Common">
<Type Name="System.Data.DataTable" Dynamic="Required All"/>
</Assembly>
Для успешной компиляции моего проекта мне пришлось сделать следующее:
Включите все ссылки в пакет nuget System.Data.SqlClient в качестве ссылок проекта. В этом случае я также включил те из System.Configuration.ConfigurationManager.
Из командной строки опубликуйте для нужной операционной системы: dotnet publish -r win-x64
Из пути публикации скопируйте файлы System.Data.SqlClient.dll и sni.dll по фиксированному пути: ..\SQLClient\win-x64\
В файле csproj сделайте условную ссылку на пакет nuget и на опубликованную dll, в данном случае через параметр MSBuild NativeCompilation.
Наконец, опубликуйте с помощью CoreRT из командной строки: dotnet publish -r win-x64 / p: NativeCompilation = true
И это сработало!
GetIPVersionSQLSRV.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup Condition="'$(BuildingInsideVisualStudio)' == 'true' OR '$(NativeCompilation)' != 'true'">
<!--System.Data.SqlClient Nuget Reference -->
<PackageReference Include="System.Data.SqlClient" Version="4.6.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.5.0" />
<!--System.Data.SqlClient References-->
<PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" />
<PackageReference Include="System.Security.AccessControl" Version="4.5.0" />
<PackageReference Include="System.Security.Principal.Windows" Version="4.5.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
<!--System.Configuration.ConfigurationManager References-->
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.5.0" />
<PackageReference Include="System.Security.Permissions" Version="4.5.0" />
</ItemGroup>
<ItemGroup Condition="'$(BuildingInsideVisualStudio)' != 'true' AND '$(NativeCompilation)'=='true'">
<!-- ILCompiler and rd.xml -->
<PackageReference Include="Microsoft.DotNet.ILCompiler" Version="1.0.0-alpha-*" />
<RdXmlFile Include="rd.xml" />
<!--System.Data.SqlClient published Dll Reference -->
<Reference Include="System.Data.SqlClient">
<HintPath>..\SQLClient\win-x64\System.Data.SqlClient.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
Program.cs
using System;
using System.Configuration;
using System.Data.SqlClient;
using System.IO;
using System.Net;
namespace GetIPVersionSQLSRV
{
class Program
{
private static String config = ConfigurationManager.AppSettings["texto"];
private static String cadena = ConfigurationManager.ConnectionStrings["default"].ConnectionString;
static void Main(string[] args)
{
Console.WriteLine("Hello World! " + config);
using(SqlConnection conn = new SqlConnection(cadena))
{
conn.Open();
using (SqlCommand comm = new SqlCommand("SELECT @@VERSION;", conn))
Console.WriteLine(comm.ExecuteScalar());
}
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(@"http://api.ipify.org?format=json");
using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
using (Stream strm = res.GetResponseStream())
using (StreamReader read = new StreamReader(strm))
Console.WriteLine(read.ReadToEnd());
req = null;
Console.ReadKey(false);
}
}
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="texto" value="CONFIG2"/>
</appSettings>
<connectionStrings>
<add name="default" connectionString="User ID=user;PWD=p455w0rd;Initial Catalog=master;Data Source=localhost"/>
</connectionStrings>
</configuration>
rd.xml
<Directives>
<Application>
<Assembly Name="System.Configuration.ConfigurationManager">
<Type Name="System.Configuration.ClientConfigurationHost" Dynamic="Required All"/>
<Type Name="System.Configuration.AppSettingsSection" Dynamic="Required All"/>
</Assembly>
</Application>
</Directives>
nuget.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<add key="dotnet-core"
value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json"/>
<add key="nuget.org"
value="https://api.nuget.org/v3/index.json" protocolVersion="3"/>
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>