How to Reference .Net Core Library in a .Net Core Console Application - macos

I am following this code example
I am on Visual Studio Community 2019 for Mac. I created a .Net Core - Class Library project and compiled to create the assembly file P1-ProgramStructure.dll.
I created another solution with program2.cs code. Please see the code below.
I renamed the .dll to acme.dll and copied the file into its directory.
Class library - .Net Core Project
Program1.cs
using System;
namespace Acme.Collections
{
public class Stack
{
Entry top;
public void Push(object data)
{
top = new Entry(top, data);
}
public object Pop()
{
if (top == null)
{
throw new InvalidOperationException();
}
object result = top.data;
top = top.next;
return result;
}
class Entry
{
public Entry next;
public object data;
public Entry(Entry next, object data)
{
this.next = next;
this.data = data;
}
}
}
}
.Net Core Console App
Program2.cs
using System;
using Acme.Collections;
class Example
{
static void Main()
{
Stack s = new Stack();
s.Push(1);
s.Push(10);
s.Push(100);
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
}
}
When I run the project, I get the error:
$ dotnet run
Program.cs(15,7): error CS0246: The type or namespace name 'Acme' could not be found (are you missing a using directive or an assembly reference?) [/Users/csarami/VisStudioProjects/cSharp Projects/Project2-ProjectStructure/Project2-ProjectStructure/Project2-ProjectStructure.csproj]
The build failed. Please fix the build errors and run again.

Make sure both projects have the same target framework

Related

TypeLoadException: Could not load type from assembly in Xamarin

I have Xamarin Forms PCL application and I am trying to inherit from HttpContent in attempt to follow this reference. I would like to implement progress bar for image upload. Here is my implementation which contains minimum code to implement HttpContent:
public class ProgressableStreamContent : HttpContent
{
public ProgressableStreamContent()
{ }
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
return Task.Run(async () =>
{
});
}
protected override bool TryComputeLength(out long length)
{
length = 0;
return true;
}
}
and I have procedure that is using this ProgressableStreamContent:
public async void UseProgressableStreamContent()
{
var progressableContent = new ProgressableStreamContent();
}
Problem is that this code produces exception:
UNHANDLED EXCEPTION: System.TypeLoadException: Could not load type 'MyApp.Classes.ProgressableStreamContent' from assembly 'MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
When I comment out line "var progressableContent = new ProgressableStreamContent();" - everything works good.
When I comment out inheritance ": HttpContent" (and override keywords) - everything works good.
Should I install some package? What else could be a problem?
I resolved issue by changing profile from 259 to 7. Changing profile includes deleting all NuGet packages and installing them again after profile change.

Compile C# on OSX using edge.js nuget package

So, I have this code from the edge.js instructions:
using System;
using System.Threading.Tasks;
using EdgeJs;
class Program
{
public static async void Start()
{
var func = Edge.Func(#"
return function (data, callback) {
callback(null, 'Node.js welcomes ' + data);
}
");
Console.WriteLine(await func(".NET"));
}
static void Main(string[] args)
{
Task.Run((Action)Start).Wait();
}
}
And I have nuget working so that I have installed edge.js with nuget install edge.js -o ./packages
But I can't figure out how to compile it on my Mac OSX. I've tried:
mcs -pkg:./packages program.cs
mcs -lib:./packages/Edgejs.0.10.0 program.cs
and a bunch other combinations. I always get this error:
error CS0246: The type or namespace name `EdgeJs' could not be found. Are you missing an assembly reference?
I have not tried monoDevelop yet. I'm hoping to get it to work with the mono command line tools so I don't need monoDevelop.
You can use -r to reference the Edgejs assembly.
mcs -r:./packages/Edge.js.0.10.0/lib/Edgejs.dll program.cs

Getting "main" Assembly version number

I have a solution with libraries (DLLs) which are used in 2 identical projects (one for WP7, another for WP8). In one of the libraries I have the code which determines the version of the application.
private static Version mVersion;
public static Version Version {
get {
if (mVersion == default(Version)) {
var lcAssembly = Assembly.GetExecutingAssembly();
var parts = lcAssembly.FullName.Split(',');
var lcVersionStr = parts[1].Split('=')[1];
mVersion = new Version(lcVersionStr);
}
return mVersion;
}
}
The problem is that this code returns the version number of the library itself because of this Assembly.GetExecutingAssembly() code. How to get a MAIN Assembly version and not DLL's?
That's a great question on code-sharing between WP7 and WP8.
The simplest way for you to do that would be to read the AppManfiest.xml file at run-time, get the EntryType and use that to get at the entry point Assembly instance. Here's how a sample AppManfiest.xml looks like once MSBuild did its magic on it:
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="myAssembly" EntryPointType="myNamespace.App" RuntimeVersion="4.7.50308.0">
<Deployment.Parts>
<AssemblyPart x:Name="myAssembly" Source="myAssembly.dll" />
</Deployment.Parts>
</Deployment>
And here's how you would read the file, get the attributes, then get the entry point type and finally the entry point assembly:
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var appManfiest = XElement.Load("AppManifest.xaml");
var entryAssemblyName = appManfiest.Attribute("EntryPointAssembly").Value;
var entryTypeName = appManfiest.Attribute("EntryPointType").Value;
Type entryType = Type.GetType(entryTypeName + "," + entryAssemblyName);
Assembly entryAssembly = entryType.Assembly;
}
That's a simple solution and it works. However, that isn't the cleanest architectural solution. The way I'd implement this solution is to have an interface declared in the shared library, both WP7 and WP8 implement that interface and register their implementation with an IoC container.
For example, let's say you need to "DoSomething" in the shared library that's platform version specific. First you'll create have an IDoSomething interface. Let's also assume you have an IoC standing by.
public interface IDoSomething
{
}
public static class IoC
{
public static void Register<T>(T t)
{
// use some IoC container
}
public static T Get<T>()
{
// use some IoC container
}
}
In your WP7 app you'll implement the shared Interface for WP7 and register it once the WP7 starts up.
public App()
{
MainPage.IoC.Register(new MainPage.DoSomethingWP7());
}
private class DoSomethingWP7 : IDoSomething
{
}
You'll also do the same for WP8 in the WP8 app. And in your shared library you can then ask for the relevant interface regardless of its platform version specific implementation:
IDoSomething sharedInterface = IoC.Get<IDoSomething>();
I have a simpler answer. I think you are close with what you are doing. I just used your code with one modification so I can use it with the Telerik controls. Here's what I did. I located your code in my project's App class (codebehind of App.Xaml). I made one change that I think will take care of your problem:
private static Version mVersion;
public static Version Version {
get {
if (mVersion == default(Version)) {
var lcAssembly = typeof(App);
var parts = lcAssembly.FullName.Split(',');
var lcVersionStr = parts[1].Split('=')[1];
mVersion = new Version(lcVersionStr);
}
return mVersion;
}
}
Now I can get the version number by calling "App.Version".
This worked for me:
var appAssembly = Application.Current.GetType().Assembly;
var appAssemblyVersion = appAssembly.GetName().Version;
I tested with WP7.1 and WP8.0.

Visual studio 2010 compilation issue

I have a project in Visual Studio 2010 with target to framework 3.5 with some code like this:
public class Test {
private object _field;
private Action defaultAction = null;
public Test(Action a)
{
defaultAction = a;
}
public Test()
: this(() => { _field = new object(); })
{
}
}
When I compile the project from the VS reports a compile error at line 11.
When I compile the project from the command line with "C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe Test.sln" compiles successfully.
In fact this code compiles in VS2008 but in VS2010 with target to framework 3.5, doesn't.
Any idea about what is happend?
Update
To fix the code in V2010 I changed as follows (this is equivalent to origian code):
public class Test {
private object _field;
private Action defaultAction = null;
public Test(Action a)
{
defaultAction = a;
}
public Test()
{
defaultAction = () => {_field = new object();}
}
}
But what worries me is that Visual Studio is compiling my code with framework 4.0 and this may cause other errors when deploying my application in the customer's environment (framework 3.5).
I don't have access to VS2008 or .NET 3.5 at the moment so I can't investigate why it's compiling for you. There might be an explanation linked from What's New in the .NET Framework 4
What I can offer however is a fix to get it compiling in VS2010. By declaring _field as static, an instance of it will be available in the constructor of the Test class.
Replace the second line of your posted code with this and the code should compile:
private static object _field;

C#5 AsyncCtp BadImageFormatException

Please help me with this one, I've been writing a console applicaiton using the AsyncCtpLibrary and the C#5 ctp compiler. First time I got to actually running a code which awaits, I got this:
System.BadImageFormatException was unhandled
Message=An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
Source=AsyncCtpLibrary
StackTrace:
Server stack trace:
at [...].<Execute>d__1c.MoveNext()
at [...].Execute()
at [...].<Move>d__1d.MoveNext() in[..]:line 266
Exception rethrown at [0]:
at System.Runtime.CompilerServices.AsyncVoidMethodBuilder.<SetException>b__1(Object state)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
InnerException:
Am I missing a dll to be referenced?
important new stuff
My failing method looks like this:
public async override Task<bool> Execute()
{
//do stuff
await stuff;
//do other stuff
await base.Execute()
//do other stuff
return true;
}
I've followed Jon Skeet's advice trying to recreate the mistake little by little, and now I can tell that the await base.Execute() line is the killer! If I comment that line out, everything runs, if I leave it in, calling my method fails IMMEDIATELY (not when reaching the base.Execute()). So I assume the ctp compiler does something freaky. Why? What should I never do? How big is the bug?
old stuff:
EDIT:
As for 32bit/64bit issue, my system is 32bit (inside a virtual machine, mind you), and as far as I know AsyncCtpLibrary.dll doesn't contain unmanaged code. All my projects (class libraries and single console app) all have build tabs like this:
What can possibly be still wrong?
EDIT:
I also checked the Fusion log viewer, the AsyncCtpLibrary is loaded without any error:
*** Assembly Binder Log Entry (6/10/2011 # 9:04:11 PM) ***
The operation was successful.
Bind result: hr = 0x0. The operation completed successfully.
Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable C:\Users\Daver\Documents\Visual Studio 2010\Projects\[...]\bin\Debug\MyApp.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = WIN-N74LV38NLV3\Daver
LOG: DisplayName = AsyncCtpLibrary, Version=1.0.4107.18181, Culture=neutral, PublicKeyToken=31bf3856ad364e35
(Fully-specified)
LOG: Appbase = file:///C:/Users/Daver/Documents/Visual Studio 2010/Projects/[...]/bin/Debug/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = MyApp.exe
Calling assembly : MyLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Users\Daver\Documents\Visual Studio 2010\Projects\[...]\bin\Debug\MyApp.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: AsyncCtpLibrary, Version=1.0.4107.18181, Culture=neutral, PublicKeyToken=31bf3856ad364e35
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:///C:/Users/Daver/Documents/Visual Studio 2010/Projects/[...]/bin/Debug/AsyncCtpLibrary.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\Users\Daver\Documents\Visual Studio 2010\Projects\[...]\bin\Debug\AsyncCtpLibrary.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: AsyncCtpLibrary, Version=1.0.4107.18181, Culture=neutral, PublicKeyToken=31bf3856ad364e35
LOG: Binding succeeds. Returns assembly from C:\Users\Daver\Documents\Visual Studio 2010\Projects\[...]\bin\Debug\AsyncCtpLibrary.dll.
LOG: Assembly is loaded in default load context.
I also checked the IL code of the <Execute>d__1c compiler-generated class' MoveNext() method, and the only assemblies it references ([assemblyName]) are mscorlib, System.Core, and AsyncCtpLibrary.
I checked the manifest of both my dll and AsyncCtpLibrary, mine said .corflags 0x00000003 // ILONLY 32BITREQUIRED, AsyncCtpLibrary said .corflags 0x00000009 // ILONLY, I'm unsure if this can be the problem.
Please help, I'm out of ideas!
EDIT: I've heard back from the compiler team, who have confirmed it as a bug. It had already been fixed in their codebase, so hopefully we'll see that fix in the next release / beta / CTP. The fix isn't going to be back-ported to "normal" VS2010 as it's a pretty unusual set of circumstances, at least before async.
EDIT: Okay, I've now got a really short but complete program which demonstrates the problem. I believe it's a mixture of generics and calling a base method:
using System;
using System.Threading.Tasks;
public abstract class AsyncAction<T>
{
public virtual Task<T> Execute()
{
// We never get this far
Console.WriteLine("Execute called");
return null;
}
}
public class BoolAction : AsyncAction<bool>
{
public async override Task<bool> Execute()
{
return await base.Execute();
}
}
class Test
{
static void Main()
{
BoolAction b = new BoolAction();
b.Execute();
}
}
EDIT: Okay, I've come up with a workaround. Basically, to call the base class method non-virtually, the compiler creates a synthetic method in BoolAction. It gets that slightly wrong, but we can get it right:
public class BoolAction : AsyncAction<bool>
{
public async override Task<bool> Execute()
{
return await BaseExecute();
}
private Task<bool> BaseExecute()
{
return base.Execute();
}
}
So whenever you were writing base.Execute, write BaseExecute and insert that extra method. It's not too bad a workaround, until the team fix the bug.
EDIT: I've simplified the example a bit - you don't need any overrides, and in particular you don't need the base class to expose a Task<T>. A call to any virtual base.Foo method will do it:
public abstract class AsyncAction<T>
{
public virtual T GetT()
{
return default(T);
}
}
public class BoolAction : AsyncAction<bool>
{
#pragma warning disable 1998 // We're not awaiting anything
public async void Execute()
{
base.GetT();
}
#pragma warning restore 1998
}
class Test
{
static void Main()
{
BoolAction b = new BoolAction();
b.Execute();
}
}
EDIT: Contrary to my previous thoughts, this does affect iterators as well. No async CTP required...
public abstract class Base<T>
{
public virtual T GetT()
{
return default(T);
}
}
public class Derived : Base<bool>
{
public System.Collections.IEnumerator Foo()
{
base.GetT();
yield break;
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
d.Foo().MoveNext();
}
}
EDIT: And it affects anonymous functions too...
using System;
public abstract class Base<T>
{
public virtual T GetT()
{
return default(T);
}
}
public class Derived : Base<bool>
{
public void Foo()
{
Action x = () => base.GetT();
x();
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
d.Foo();
}
}
You are hitting known VS 2010 bug
https://connect.microsoft.com/VisualStudio/feedback/details/626550/badimageformatexception-on-simple-program-using-generics-and-lambdas
This exception often occurs when you try and load a 32 bit DLL in a 64 bit environment.
If you are running on a 64 bit OS try changing your projects settings to compile directly for x86 (rather than AnyCPU).
(This might sound backwards, but it's because if you are loading an external 32 bit DLL you need to force your whole project to be 32 bit.)

Resources