SQLite3 Connection Causes Confusing Compile Error - c#

I am attempting to compile my Xamarin project and I am getting a compiler error that I dont understand. What does the following error mean and how can i fix this?
Data\SQLiteClient.cs(4,4): Error CS0012: The type 'System.Threading.Tasks.TaskScheduler' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Threading.Tasks, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. (CS0012) (DtoToVm.Droid)
Relevant information:
Xamarin Forms blank project PCL
Project set to .NET 4.5 or later
Profile: PCL 4.5 - Profile78
Alot of references are not happy but I haven't manually setup or editted these. Maybe a nuget package conflict?
using Xamarin.Forms;
using DtoToVm.Droid.Data;
[assembly: Dependency (typeof(SQLiteClient))]
namespace DtoToVm.Droid.Data
{
using System;
using DtoToVm.Data;
using SQLite.Net.Async;
using System.IO;
using SQLite.Net.Platform.XamarinAndroid;
using SQLite.Net;
public class SQLiteClient : ISQLite
{
public SQLiteAsyncConnection GetConnection ()
{
var sqliteFilename = "Conferences.db3";
var documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
var path = Path.Combine (documentsPath, sqliteFilename);
var platform = new SQLitePlatformAndroid ();
var connectionWithLock = new SQLiteConnectionWithLock (
platform,
new SQLiteConnectionString (path, true));
// The below line causes the compile error
var connection = new SQLiteAsyncConnection (() => connectionWithLock);
return connection;
}
}
}
Edit:
According to this thread I shd change the profile to 7. I've done this and it got rid of all errors but produced a new one:
DtoToVm\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.dll: Error CS1703: An assembly with the same identity 'System.Net.Http, Version=1.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' has already been imported. Try removing one of the duplicate references. (CS1703) (DtoToVm)
What file could this duplicate reference be in?

I don't really know if System.Threading.Tasks namespace exists in Xamarin or not, If it's exists then reference it, If not then use the regular SqliteConnection and don't use Async one.

Related

C# type conflicts only when explicitly referenced

I have the following code in my project, this compiles and run (seemingly) properly.
SpeechClient.StreamingRecognizeStream streamingCall;
[...]
while (await streamingCall.ResponseStream.MoveNext(CancellationToken.None))
{
[...]
}
In visual studio, hovering over streamingCall.ResponseStream tells me that it is of type System.Collections.Generic.IAsyncEnumerator<StreamingRecognizeResponse>. However the following code
System.Collections.Generic.IAsyncEnumerator<StreamingRecognizeResponse> responseStream = streamingCall.ResponseStream;
while (await responseStream.MoveNext(CancellationToken.None))
{
[...]
}
does not compile with the error:
CS0433 The type 'IAsyncEnumerator<T>' exists in both
'System.Interactive.Async, Version=3.2.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263'
and
'mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'
Replacing System.Collections.Generic.IAsyncEnumerator<StreamingRecognizeResponse> by var however does fix the error. The following code, compiles and run properly.
var responseStream = streamingCall.ResponseStream;
while (await responseStream.MoveNext(CancellationToken.None))
{
[...]
}
Why is the compiler confused when I use the real type, but not when referring it via either var or via a property?
How do I modify the code in order to be able to use the type directly, e.g. to take it as a function parameter?
If that matters, I am running this code on iOS with Xamarin.Forms.
In the project having this compilation error, try removing a reference to System.Interactive.Async assembly/package and try recompiling...

Roslyn compilation - how to reference a .NET Standard 2.0 class library

I created a console application project (targeting .NET Core 3.0) and a class library (targeting .NET Standard 2.0). The console application tries to use the Roslyn compiler to compile some C# code that references that previously created class library. I'm hitting some major issues though.
Here's the code for the console application (note that most of it is example code from https://github.com/joelmartinez/dotnet-core-roslyn-sample/blob/master/Program.cs):
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp; //nuget Microsoft.CodeAnalysis.CSharp
using Microsoft.CodeAnalysis.Emit;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
//This is a class library I made in a separate project in the solution and added as a reference to the console application project.
//The important bit for the reproduction of the issue is that ClassLibrary1 targets .NET Standard 2.0.
using ClassLibary1;
namespace RoslynIssueRepro
{
class Program
{
static void Main(string[] args)
{
string codeToCompile =
#"
using ClassLibary1;
using System;
namespace RoslynCompileSample
{
public class Writer
{
public void Execute()
{
//1. this next line of code introduces the issue during Roslyn compilation (comment it out and everything runs fine).
//It causes the code to reference a .NET Standard 2.0 class library (and this console app targets .NET Core 3.0).
//Note: If the referenced class library targets .NET Core 3.0, everything works fine.
//The error looks like this:
// CS0012: The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.
Console.WriteLine(Class1.DoStuff());
Console.WriteLine(""Freshly compiled code execution done!"");
}
}
}";
var refPaths = new[] {
typeof(System.Object).GetTypeInfo().Assembly.Location,
typeof(Console).GetTypeInfo().Assembly.Location,
Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Runtime.dll"),
typeof(Class1).GetTypeInfo().Assembly.Location,
//2. So adding a reference to netstandard.dll to alleviate the issue does not work.
//Instead it causes even more compilation errors of this form:
// CS0518: Predefined type 'System.Object' is not defined or imported
// CS0433: The type 'Console' exists in both 'System.Console, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' and 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
//Go ahead and try it by uncommenting the line below:
//Environment.ExpandEnvironmentVariables(#"C:\Users\%USERNAME%\.nuget\packages\netstandard.library\2.0.0\build\netstandard2.0\ref\netstandard.dll")
};
RoslynCompileAndExecute(codeToCompile, refPaths);
}
#region example code from https://github.com/joelmartinez/dotnet-core-roslyn-sample/blob/master/Program.cs
private static void RoslynCompileAndExecute(string codeToCompile, string[] refPaths)
{
Write("Let's compile!");
Write("Parsing the code into the SyntaxTree");
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(codeToCompile);
string assemblyName = Path.GetRandomFileName();
MetadataReference[] references = refPaths.Select(r => MetadataReference.CreateFromFile(r)).ToArray();
Write("Adding the following references");
foreach (var r in refPaths)
Write(r);
Write("Compiling ...");
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
syntaxTrees: new[] { syntaxTree },
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var ms = new MemoryStream())
{
EmitResult result = compilation.Emit(ms);
if (!result.Success)
{
Write("Compilation failed!");
IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
diagnostic.IsWarningAsError ||
diagnostic.Severity == DiagnosticSeverity.Error);
foreach (Diagnostic diagnostic in failures)
{
Console.Error.WriteLine("\t{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
}
}
else
{
Write("Compilation successful! Now instantiating and executing the code ...");
ms.Seek(0, SeekOrigin.Begin);
Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
var type = assembly.GetType("RoslynCompileSample.Writer");
var instance = assembly.CreateInstance("RoslynCompileSample.Writer");
var meth = type.GetMember("Execute").First() as MethodInfo;
meth.Invoke(instance, null);
}
}
}
static Action<string> Write = Console.WriteLine;
#endregion
}
}
and the code for the ClassLibrary1 is just this:
namespace ClassLibary1
{
public static class Class1
{
public static string DoStuff()
{
return "asdfjkl";
}
}
}
I've commented two places in code with //1 and //2. The first one is the line that introduces the first issue, and causes the compilation to fail. The second spot (currently commented out) is an attempt to work around the first issue by adding a reference to the netstandard.dll file (sorry if the path isn't portable, just where I happened to find it on my machine), but it does not fix anything, only introducing more cryptic errors.
Any idea on the approach I should take to get this code to work?
The first error occur because your referenced library targets netstandard and the console app compilation which references this library must reference netstandard.dll to correctly resolve all corresponding types. So you should add reference to nestandard.dll but it's not all and here you get the second error.
When you try to reference netsandard directly or by transitive you must provide the nestandard.dll corresponding by the target platform. And this netstandard will have a huge of forwarding types to the types on the current target platform. If you look at the #"C:\Users\%USERNAME%\.nuget\packages\netstandard.library\2.0.0\build\netstandard2.0\ref\netstandard.dll" you will find that this netstandard.dll doesn't contain forwards but contains all types directly and of course it contains System.Console. ( I think, it contains all types directly because it is from nuget package which doesn't depend on any target platform, but really not sure for that). And when you try to add it and System.Console.dll by typeof(Console).GetTypeInfo().Assembly.Location you actually get two System.Console in a compilation.
So to resolve this ambiguous you can add netstandard not from this nuget package, but from you current target platform which has all needed forwards. For the .netcore30, for example, you can use netstandard from path_to_dotnet_sdks\packs\Microsoft.NETCore.App.Ref\3.0.0\ref\netcoreapp3.0\ (be careful this assemblies and assemblies from nuget package above just for referencing, they doesn't contain real logic). Also you may try to remove reference on System.Console.dll and keep reference on #"C:\Users\%USERNAME%\.nuget\packages\netstandard.library\2.0.0\build\netstandard2.0\ref\netstandard.dll"
Since you're using typeof(X).Assembly to locate all other referenced assemblies, which will implicitly return the assemblies loaded into your App Domain. I would recommend locating the matching netstandard in the same way. However, since netstandard doesn't directly define any types, the best method I've found is to search for it by name;
AppDomain.CurrentDomain.GetAssemblies().Single(a => a.GetName().Name == "netstandard")
var dd = typeof(Enumerable).GetTypeInfo().Assembly.Location;
var coreDir = Directory.GetParent(dd);
MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "netstandard.dll")
Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), "netstandard.dll")

UWP - SQLite issues when compiling in native

I was developing my app using SQLite, on "Debug" mode, worked perfectly.
When I try to "Release" it (Compiling "Native"), the problem started, looks like UWP doesn't support Reflexion.
I'm currently using this packages:
SQLite.Core.UAP
SQLite.Net-PCL
For example, if I try to do this:
private void CreateDatabase()
{
var dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "StoredEvents.sqlite");
SQLiteConnection SQLiteConn = new SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), dbPath, false);
SQLiteConn.CreateTable<StoredEvents>();
}
These are some of the error:
ILTransform_0027: Method 'CreateLambda' within 'System.Linq.Expressions.Expression' could not be found.
Error at SerializationAssemblyGenerator.Program.AddKnownContractsLists(McgCodeTypeDeclaration container, ContractTables tables)
Severity Code Description Project File Line Suppression State
Error at SerializationAssemblyGenerator.Program.GenerateDataContractSerializerHelperCode(IEnumerable`1 contracts, IEnumerable`1 jsonContracts, IEnumerable`1 wcfSerializers)
ILTransform_0000: MCG : warning MCG0006: Unresolved P/Invoke method '_TPM_Init!tpm.dll' in assembly 'TSS.UWP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it is not available in UWP applications. Please either use an another API , or use [DllImport(ExactSpelling=true)
How should I refactor the code?
Should I use a different Library?
I had the same issue when i was updating my apps from Silverlight to UWP. I read an article somewhere ( Tried to find it but was unable to ) which says SQLlite for UWP is available for Windows 10 deployment.
The above is a VS Extension. You can get there from Tools ->> Extensions & Updates
Below is how my References look like.
Also I noticed that you are not closing your db connection. Always better to use it inside a using statement. your CreateTables() will look something like below.
private void CreateDatabase()
{
var dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "StoredEvents.sqlite");
using (SQLiteConnection SQLiteConn = new SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), dbPath, false))
{
SQLiteConn.CreateTable<StoredEvents>();
}
}

System.Data.Entity.Design.PluralizationServices Error in Mono

I have a mature C# application that has always been run on Windows that is being ported to Linux (on Mono), and I am running into an error that I cannot resolve regarding PluralizationServices in System.Data.Entity.Design.
The line of code causing the problems is as follows:
PluralizationService pluralizationService = PluralizationService.CreateService(System.Globalization.CultureInfo.InvariantCulture);
Although this has never caused any problems on the Windows application running under Microsoft.NET, when the program is running under Mono I get the following error:
Unhandled Exception:
System.IO.FileNotFoundException: Could not load file or assembly 'System.Data.Entity.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies.
File name: 'System.Data.Entity.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
I found here someone else who seemed to be having a similar problem had simply copied the .NET version of the .dll over to their Mono project, and it resolved the issue for them. I tried the same, however I then encountered the following error:
Unhandled Exception:
System.TypeInitializationException: An exception was thrown by the type initializer for MudSharp.Framework.LanguageHelpers ---> System.InvalidProgramException: Invalid IL code in System.Data.Entity.Design.PluralizationServices.PluralizationService:CreateService (System.Globalization.CultureInfo): method body is empty.
I'm using Mono 3.10 on Ubuntu. I can't find any suggestion that Mono doesn't support these functions, and I'm simply unsure how to proceed with debugging this issue.
Any help would be appreciated.
Looks like latter versions of Mono do support the PluralizationService - see function support status.
However, the PluralizationService currently only supports English.
Have you tried this:
PluralizationService pluralizationService = PluralizationService.CreateService(CultureInfo.GetCultureInfo("en-us"));`
FYI, looks easy enough to extend to other languages using the EntityModelSchemaGenerator class.
Plurally is a Mono-compatible replacement to the Entity Framework pluralization services.
use Plurally test library source code jsonclassgenerator
IDE: Xamarin Studio 6.1.3
framework: Mono / .NET 4.5
add NuGet package: Newtonsoft.Json, Plurally
JsonClassGenerator.cs line 10,39
use Plurally.Pluralizer
using Plurally;
private Pluralizer pluralizationService = new Pluralizer(new CultureInfo("en-us"));
JsonType.csline 8
using Plurally;
Xamasoft.JsonClassGenerator.JsonClassGenerator GenerateClasses Result
{
"UserAccount": "",
"UserPassword": "",
"ExtraInfo": ""
}
// Generated by Xamasoft JSON Class Generator
// http://www.xamasoft.com/json-class-generator
using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
namespace CommonModels
{
public class loginArgs
{
public string UserAccount { get; set; }
public string UserPassword { get; set; }
public string ExtraInfo { get; set; }
}
}

RegistrationServices.RegisterAssembly error - help!

I have an assembly on a shared folder (UNC-path only, no mapped drive). When I try to register it programmatically via RegistrationServices, I'm getting a strange error.
Here's the code:
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
namespace BLRegisterAssembly
{
public static class BlRegisterAssembly
{
public static void Register()
{
var asm = Assembly.LoadFile(#"\\myUNCPath\myAssembly.dll");
var rs = new RegistrationServices();
rs.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase);
// I've also tried AssemblyRegistrationFlags.None : same error.
}
}
}
This is the error I'm getting:
"Could not load file or assembly
'[xxxxxxxxxxxxx],
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=[xxxxxxxxxxxxxx]' or
one of its dependencies. The system
cannot find the file specified."
(The file in question is a referenced assembly that the main assembly uses).
Some more points:
- the referenced assembly is located in the same folder as the main assembly that I'm trying to register.
- the folder cannot be mapped as a logical drive. Because of how the network folders are accessed, users in different groups have different drive mappings to the same network folders, and these cannot be modified, per IT policy...
Can anyone point me in the right direction to resolve the problem?
ANSWERED
Because I was using Assembly.LoadFile, the dependent assemblies have to be resolved manually via AssemblyResolve. The following code update fixed my woes:
public void Register()
{
AppDomain.CurrentDomain.AssemblyResolve +=
new ResolveEventHandler(CurrentDomain_AssemblyResolve);
var asm = Assembly.LoadFile(Path.Combine(m_path, assemblyName));
var rs = new RegistrationServices();
rs.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase);
}
static Assembly CurrentDomain_AssemblyResolve(object sender,
ResolveEventArgs args)
{
//... code to resolve the path and load the dependent assembly...
}
You should never use LoadFile(), use LoadFrom() so the CLR has a shot at finding any dependent assemblies. If you still have trouble then use Fuslogvw.exe to get a trace of the assembly resolution attempt. The backup plan is to implement AppDomain.AssemblyResolve.

Categories

Resources