How to use .Net DLL in Uno Platform WASM? - c#

I'd wrote a DLL in .net.
I use it in UNO Platform for UWP. Now i'd like tu use some function of this DLL in WASM project.
Is it Possible ?
In UWP i connect the DLL in reference folder.
In WASM how can i done ?
Thanks

I'm assuming your .NET project file has references to UNO WASM bootstrap packages. If not add them like this.
<ItemGroup>
<PackageReference Include="Uno.Wasm.Bootstrap" Version="2.1.0" />
<PackageReference Include="Uno.Wasm.Bootstrap.DevServer" Version="2.1.0" PrivateAssets="all" />
</ItemGroup>
Once this is done and your .NET project is able to build and run as WASM. There should a bunch of files generated by UNO Bootstrap WASM in the /bin folder of .NET project. Some of those include
uno_bootstrap.js
dotnet.js
dotnet.wasm
Look at JS code in first two, uno-bootstrap.js is the entry point, which will call dotnet.js which will have JS bindings into WASM. This will also list any DLLs that are linked into WASM. YOu can add your DLL here.

Related

MAUI and platform binding libraries

I'm trying to setup a MAUI app primarily for Windows and Android devices. I have a BT printer that the supplier provides libraries (in form of JAR and DLL files) for.
I'm trying to add to the MAUI app the JAR library using the Android Java Library Binding as a separate project. The project builds itself but, when I add to the MAUI app, I receive errors regarding the lack of support by the library for other platforms (iOS, Windows).
Reading some other threads the solution should be to add a MAUI class library (where for every platform I can add specific code) but I don't know how can wrap the JAR library into it for Android.
In Xamarin Forms it's more simple: refer the Android Binding Library (Xamarin) by the app.android project and all is done.
So can I do the same for MAUI? Can I have one printer library for every platform I want to support and, via iOC, refer the right library for the right platform?
Thanks in advance Andrea.
just for someone that has the same question, I have resolved editing by hand the csproj file and adding conditional project referencing like this:
<ItemGroup Condition=" '$(TargetFramework)' == 'net6.0-android31.0' ">
<ProjectReference Include="..\Your.CodeFor.Android\Your.CodeFor.Android.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net6.0-windows10.0.19041.0' ">
<ProjectReference Include="..\Your.CodeFor.Windows\Your.CodeFor.Windows.csproj" />
</ItemGroup>
Now I can specify different project reference for different platforms, only an IntelliSense warning appears when use the reference that lacks code for platforms that is not intended for.
Andrea.

How do I make NuGet aware of a specific version of a package while referencing a multi-targeted class library?

We have three projects:
WebApp.csproj, ASP.NET WebForms app compiled against .NET Framework 2.0
Api.csproj, ASP.NET WebApi 2 compiled against .NET Framework 4.5
Lib.csproj, compiled against .NET Framework 2.0 and referenced by both of the projects above.
Lib.csproj has been recreated in the new .NET project format (the one used by .NET Core) and made to target both .NET Fw 2.0 and 4.5 with the <TargetFrameworks>net20;net45</TargetFrameworks> technique.
So far so good, I can reference different NuGet packages by writing the appropriate sections in Lib.csproj like so:
<ItemGroup Condition="'$(TargetFramework)' == 'net20'">
<PackageReference Include="NLog" Version="2.1.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<PackageReference Include="NLog" Version="4.7.8.0" />
</ItemGroup>
and I can point Api.csproj to the version of Lib.csproj targeting net45, like so:
<ProjectReference Include="..\..\Lib\Lib.csproj" AdditionalProperties="TargetFramework=net45">
<Project>{32e77bcf-152c-4b64-be37-a13f49cdcab6}</Project>
<Name>Lib</Name>
</ProjectReference>
The net20 version references NLog 2.1.0, the net45 one NLog 4.7.8.
The problem: now I want to use NLog 4.7.8 in my Api.csproj, but when I click on Manage Packages for Solution on the solution that includes Api.csproj and Lib.csproj, the referenced version appears to be 2.1.0.
I tried selecting both projects and installing it, however I rightly get an error because NLog 4.7.8 is not compatible with net20.
So really, the problem is that NuGet does not seem to be aware that the project I'm referencing is a multi-target one, and only sees the version of NLog installed in the net20 version even though Api.csproj is targeting the right "flavor" of Lib.csproj (and if I go and check the binaries, the version of NLog.dll that gets copied to the output folders is the right one for each of my targets).
I tried looking on the interwebs, but to no avail.
To be fair: the version of NLog that gets copied to Api.csproj's bin folder is the right one, so it's not a showstopper. But it is mildly annoying, because NuGet shows the wrong version of my dependency, and then it's hard to tell what version we're actually using.
For a bit of context: this app is obviously ancient, at least WebApp.csproj. Due to performance reasons, we are making Api.csproj use async/await, and since that project references code that could be made async in Lib.csproj but obviously wouldn't compile under .NET 2, we chose to make Lib.csproj multi-targeted.
The AdditionalProperties here shouldn't be necessary:
<ProjectReference Include="..\..\Lib\Lib.csproj" AdditionalProperties="TargetFramework=net45">
<Project>{32e77bcf-152c-4b64-be37-a13f49cdcab6}</Project>
<Name>Lib</Name>
</ProjectReference>
I strongly recommend updating all your projects to use SDK-style csproj format if possible. This isn't possible for legacy (pre-Core) web projects, which is the case for WebApp.csproj and Api.csproj. However, even those projects can use some parts of the newer csproj format.
Specifically, they can use PackageReference. I assume your existing web projects are using nuget.config, but they can be changed to use PackageReference without actually making them SDK-style csprojs. NuGet has some issues with transitive dependencies when nuget.config is used, so I just recommend using PackageReference everywhere.

What is the content of .Net publish resulting exe?

I published a small C# .Net Core 2.2 console application as executable using the following command from this post:
dotnet publish -c Release -r win10-x64
The generated files contain both the classic ConsoleApp.dll, but also the executable that I was expecting to be generated ConsoleApp.exe.
My question is why there was still the DLL generated, since all its code, I suppose, could have been compiled to the .exe, as in a .Net Framework application?
On the other hand, I tried to decompile the .exe file with ILSpy but the content from it does not seem to be managed code. In this case I also suppose that the .exe file is just calling the DLL using the dotnet command. Is this assumption right?
Below is the Console Application .csproj file content:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Management" Version="4.7.0-preview3.19551.4" />
</ItemGroup>
<ItemGroup>
<None Update="input.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Very interesting question. I'll try to cover it as much as I possibly can.
With the introduction of .net core 3.0 came the Single file publish as described in the design documentation of .Net. So If you have a .net 3.0 application then you can use the /p:PublishSingleFile=true to bundle everything in a single executable.
Watch out for the /p:PublishTrimmed=true option, as treeshaking can and probably will cause problems with reflection code, as access to it is not covered by the tree shaking.
For previous versions of net core, you need to use one of the packagers like wrap or Costura.
As per the exe file, I'll mention somthing from the wrap documentation:
The final self-contained single binary application consists of two
parts: 1) runner and 2) the compressed target application executable
and dependencies.
The dll that is created by the standard publisher is multi platform and non specific to windows. So the executable file has all the code needed to create the process in windows and call the actual code that is in the dll that can be used on any platform. It's just a wrapper.
More information about the executable Microsoft .net core deploying docs
Self-contained deployment. Unlike FDD, a self-contained deployment
(SCD) doesn't rely on the presence of shared components on the target
system. All components, including both the .NET Core libraries and the
.NET Core runtime, are included with the application and are isolated
from other .NET Core applications. SCDs include an executable (such as
app.exe on Windows platforms for an application named app), which is a
renamed version of the platform-specific .NET Core host, and a .dll
file (such as app.dll), which is the actual application.
I am not sure about your assumption. But use the following command it will generate only two files, one is .exe and other is .pdb in the publish directory inside win10-x64 directory.
dotnet publish -r win10-x64 -c Release /p:PublishSingleFile=true /p:PublishTrimmed=true

Reference a UWP project from a .NET core project

I have some code in a Universal Windows class library I want to use from a .NET core project.
I have a pi running Windows IOT for which I installed adafruits PWM hat. I have found an UWP project containing the needed C# code and that works great.
But at the pi I also want to have an asp.net core project that uses the UWP project. But if I add a reference from my asp.net core to UWP it tells that it is not supported which also make sense as they are at same level in the .net architecture.
I use Visual Studio 2019 and just installed .NET Core 3.0 preview3.
Any way I can achive to use the UWP from my core project?
If you want to reference, it can't be done as you said yourself it makes no sense.
Some workaround would be to move the code from UWP project to the new .Net Core project and then reference it from both projects. If you use some UWP APIs you might consider to use a shared project with conditional compiling instead of the new .Net Core project.
Try adding
<ItemGroup>
<PackageReference Include="System.Runtime.WindowsRuntime" Version="4.6.0-preview4.19212.13" />
<Reference Include="Windows">
<HintPath>C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.18362.0\Windows.winmd</HintPath>
</Reference>
</ItemGroup>
to your csproj file. It allowed me to use UWP api in asp.net core preview 3 project.

multi-platform native libraries in C# nuspec

We have a C# project (.net Core) which is cross-platform. It uses native libraries (C++), which are different for each platform.
We know that you can specify different frameworks in a single nuspec file, but this case is different:
There will be a single C# DLL file
There will be different native libraries (like a.linux.so and a.windows.dll)
We want be able to install only the libraries that are pertinent to a specific OS.
What is the recommended mechanism?
First, make sure you are using SDK-based projects to ensure you get correct dependency trimming for target frameworks like netstandard* (instead of using a .nuspec file).
The goal is to separate your native runtime assets into a runtimes subfolder inside your NuGet folder so that the layout is:
\lib\YourManagedCode.dll
\runtimes\win-x86\native\some.dll
\runtimes\win-x64\native\some.dll
\runtimes\linux-x64\native\libsome.so
\runtimes\osx-x64\native\some.dylib
An example project file could look like this, assuming you already have runtimes folder:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None Update="runtimes\**" Pack="true" PackagePath="runtimes" />
</ItemGroup>
</Project>
If you need to test locally, you can also add CopyToOutputDirectory="PreserveNewest" to ensure the files are copied to the output. .NET Core should be able to resolve files located in runtimes directories for methods annotated with [DllImport("some")].
The resulting NuGet package can be referenced from both .NET Core and .NET Framework projects. If some "RID-fallback" (e.g. win10-x64 => win-x64) does not work on .NET Framework projects, make sure this project also references a recent version of the Microsoft.NETCore.Platforms package (it provides NuGet with a graph of known values, has nothing much to do with .NET Core itself..).

Categories

Resources