#c# #code-generation #roslyn #c#-9.0
#c# #генерация кода #рослин #c #-9.0
Вопрос:
На мой генератор кода netstandard 2.0 ссылаются из консольного приложения core 5.0.
Csproj выглядит следующим образом
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>9.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Func" Version="0.2.2" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.8.0" PrivateAssets="all"/>
</ItemGroup>
<ItemGroup>
<!-- Generator dependencies -->
<PackageReference Include="Microsoft.Data.SqlClient" Version="2.1.1" GeneratePathProperty="true" PrivateAssets="all" />
</ItemGroup>
<PropertyGroup>
<GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn>
</PropertyGroup>
<Target Name="GetDependencyTargetPaths">
<ItemGroup>
<!--<TargetPathWithTargetPlatformMoniker Include="$(PKGSystem_Security_Principal_Windows)runtimeswinlibnetstandard1.3System.Security.Principal.Windows.dll" IncludeRuntimeDependency="false" />-->
<TargetPathWithTargetPlatformMoniker Include="$(PKGMicrosoft_Data_SqlClient)runtimeswinlibnetstandard2.0Microsoft.Data.SqlClient.dll" IncludeRuntimeDependency="false" />
</ItemGroup>
</Target>
</Project>
и ссылается на Microsoft.Data.SqlClient.
при попытке создать новый SqlConnection
, подобный этому
_dbConnection = new SqlConnection();
_dbConnection.ConnectionString = @"validconnectionstring";
_dbConnection.Open();
При открытии соединения выдается исключение с сообщением:
Could not load file or assembly 'System.Security.Principal.Windows, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
Source:
Microsoft.Data.SqlClient
Stacktrace:
at Microsoft.Data.ProviderBase.DbConnectionPoolIdentity.GetCurrentNative()
at Microsoft.Data.ProviderBase.DbConnectionPoolGroup.GetConnectionPool(DbConnectionFactory connectionFactory)
at Microsoft.Data.ProviderBase.DbConnectionFactory.GetConnectionPool(DbConnection owningObject, DbConnectionPoolGroup connectionPoolGroup)
at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternalamp; connection) at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions)
at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides)
at CSharp.Data.Sql.Schema.Provider.SqlServer.DbConnectionAsync..ctor() in C:DevCSharpSQLProviderSQLProviderCSharp.Data.SqlSchemaProviderSqlServerDbConnectionAsync.cs:line 18
at CSharp.Data.Sql.Generator.DataContextGenerator.Execute(GeneratorExecutionContext context) in C:DevCSharpSQLProviderSQLProviderCSharp.Data.SqlGeneratorDataContextGenerator.cs:line 57
Исключение Innerexception равно нулю.
Чтобы было ясно, я могу создать экземпляр SqlConnection только при установке строки подключения, выдается эта ошибка. Я также попробовал System.Data.SqlClient, однако мне не удалось создать экземпляр SqlConnection, но было выдано то же исключение, только с другим именем сборки.
Я также попытался добавить зависимость в csproj таким же образом, как и для Microsoft.Data.SqlClient в приведенном примере, но безрезультатно, также попытался загрузить требуемые сборки в домен приложения, а также попытался добавить сборку в контекстную компиляцию.
var assembly = Assembly.LoadFrom(@"C:Users{user}.nugetpackagessystem.security.principal.windows4.4.1runtimeswinlibnetcoreapp2.0System.Security.Principal.Windows.dll");
var refe = MetadataReference.CreateFromFile(assembly.Location);
var foo = context.Compilation.ExternalReferences.Add(refe);
var d = context.Compilation.AddReferences(new[] { refe });
Я подозреваю, что я делаю что-то не так, и любая помощь будет оценена. Спасибо.
Я должен также упомянуть, что отсутствующая сборка находится отдельно от возвращенных сборок в AppDomain.CurrentDomain.GetAssemblies() в методе execute
Комментарии:
1. просто добавьте пакет в приложение
2. Это не работает, это не время выполнения, это время компиляции, и вы должны использовать msbuild в csproj, чтобы сделать это с помощью <TargetPathWithTargetPlatformMoniker смотрите также github.com/dotnet/roslyn-sdk/blob/master/samples/CSharp /… это не так просто, как добавить ссылку
3. Я сталкиваюсь с теми же проблемами при попытке использовать SqlClient в анализаторе. Проблема в том, что вам нужно использовать правильные зависимости для среды выполнения компиляции. Я подозреваю, что сборки пакета недостаточно. Для корректной работы анализатору требуется все, начиная с публикации (с идентификатором RuntimeIdentifier текущей платформы компилятора — особенно содержимое папок runtimes).
4. Мне кажется странным, что вы объединяете .NET Standard 2.0 и C # 9. AFAIK это недопустимая конфигурация
5. При желании вы можете объединить netstandard2.0 и C # 9. Это может привести к возникновению проблем, которые трудно определить. Если вы не используете неподдерживаемый синтаксис, все в порядке.
Ответ №1:
вы можете сопоставить требуемую сборку с требуемой версией в app.config, как показано ниже.
<dependentAssembly>
<assemblyIdentity name="System.Security.Principal.Windows" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="4.1.1.0" />
</dependentAssembly
Комментарии:
1. Что делать, если нет файла app.config? это для проекта netstandard 2.0.
2. Добавьте сопоставление в клиентское приложение .net 5, из которого вызывается стандартная сборка .net
3. Спасибо, но это не работает. Я добавил app.config в консольное приложение, чтобы xml выглядел так
<?xml version="1.0" encoding="utf-8" ?> <configuration> <dependentAssembly> <assemblyIdentity name="System.Security.Principal.Windows" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="4.1.1.0" /> </dependentAssembly> </configuration>
же, как и при создании консольного приложения и запуске генератора кода4. Вы проверяли, имеет ли файл конфигурации, созданный после сборки проекта, сопоставление
5. Вы должны использовать msbuild для добавления ссылок во время компиляции генератора, см. Эти примеры github.com/dotnet/roslyn-sdk/blob/master/samples/CSharp /… в качестве примера