MAUI and platform binding libraries - c#

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.

Related

How to use .Net DLL in Uno Platform WASM?

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.

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.

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..).

How can I implement Dotfuscator on a .NET Standard 2.0 project?

I'm in the process of of upgrading an existing Xamarin app from PCL to .NET Standard 2.0.
I have several sub-projects such as business, data, BDO etc. which were PCL, I've been able to update them to .NET Standard 2.0 using this tutorial.
However I have Dotufscator implemented on all my PCL projects using this Xamarin Blog implementation, but it does not appear to work as an instruction for .NET Standard 2.0 projects. The DLL is not obfuscated and the 'Running Dotfuscator' message does not show in the Build Output.
My current attempt at adding Dotufcator to a .NET Standard 2.0 proj file is as follows:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<DotfuscatorXamarinCliPath>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Extensions\PreEmptiveSolutions\DotfuscatorCE\dotfuscatorCLI.exe</DotfuscatorXamarinCliPath>
<DotfuscatorXamarinConfigFileName>DotfuscatorConfig.xml</DotfuscatorXamarinConfigFileName>
<DotfuscatorXamarinGenerateNewConfigFile>true</DotfuscatorXamarinGenerateNewConfigFile>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>bin\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DotfuscatorXamarinEnabled>true</DotfuscatorXamarinEnabled>
<OutputPath>bin\Release\</OutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
</ItemGroup>
<ItemGroup>
<None Include="DotfuscatorConfig.xml" />
</ItemGroup>
<Import Project="..\PreEmptive.Dotfuscator.Xamarin.targets" />
</Project>
Would anyone be able to help?
Thanks
As a disclaimer, I should mention I'm answering this post as part of my job as a developer and technical writer on the Dotfuscator team.
I also wrote the blog post you linked to, so I'm glad you've found it valuable in protecting your Xamarin app.
First, there's an ambiguity in the blog post that I should clear up.
The Dotfuscator-Xamarin MSBuild integration shown there is only intended to be integrated into platform-specific Xamarin projects which build into a packaged format, like an Android project that builds an APK.
Integrating directly into library projects like Portable Class Libraries (PCLs) or .NET Standard Libraries isn't supported.
Note that integrating Dotfuscator into a Xamarin project will protect all packaged assemblies that originated from your solution, so your library code will still be protected.
For instance, if you integrate Dotfuscator into MyApp.Android.csproj, which references A.csproj, B.csproj, and C.csproj, Dotfuscator will protect all four projects' assemblies when they are packaged into the APK.
This approach allows for stronger protection and doesn't require you to run Dotfuscator for each library separately, saving you build and configuration time.
If you are using the commercially-licensed Dotfuscator Professional Edition, version 4.37.0 includes a new MSBuild integration.
The new integration is easier to set up, fixes some known issues, and going forward will be the primary way we recommend using Dotfuscator, for projects of all kinds, not just Xamarin.
I recommend upgrading Dotfuscator to this version and removing the Dotfuscator-Xamarin MSBuild integration from your .NET Standard projects.
Then, add the new MSBuild integration to your platform-specific Xamarin projects; for details, see the Xamarin Getting Started page of our User Guide.
If you are using Dotfuscator Community Edition (included with all Visual Studio editions) or an older Professional Edition, please continue to use the Dotfuscator-Xamarin MSBuild integration mentioned by the blog post.
I recommend you remove the integration from your .NET Standard Libraries and instead add it into the platform-specific Xamarin projects that reference them.
Note that when integrating into a Xamarin project that references .NET Standard Libraries, there is a known issue where the first build will fail (because the integration doesn't understand the minimal project format .NET Standard uses); see this answer for a workaround.
Subsequent builds will occur normally without needing a workaround.

Categories

Resources