I have a Solution with .NET Framework Project A which builds a winforms application containing a class, MyPlayer which requires LibVLCSharp. In order for the application to build and run correctly I had to add the following Nuget packages:
LibVLCSharp
LibVLCSharp.WinForms
VideoLAN.LibVLC.Windows
Now I want to move class MyPlayer to a separate .NET Standard class library, Project B, to separate out function from UI and so that it can be used by multiple other projects targeted to different platforms. In order for B to compile I only had to add the LibVLCSharp Nuget package. Then I set B as a Reference for A.
Obviously, Project A is going to require the other two Nuget packages somehow, but I am unsure to which project it is most appropriate to add them. What makes the most sense in this situation? Or is there really only one way it would work?
that's a good question, and I don't know if it is properly documented on LibVLCSharp.
Short Answer:
LibVLC must always be referenced on the executable project (A)
WinForms isn't compatible with .net standard, so you can't reference it in B if you keep using netstandard.
LibVLCSharp can be moved "up" in project B if you need it there.
Long answer:
Let's see the packages in detail:
VideoLAN.LibVLC.Windows : This package contains the required dlls files that are required to make libvlc work on Windows. It also contains msbuild files that are used to copy the DLLs to the output directory of your project. You need those files in your application, so you need to reference this package in A. (They won't be transitively copied by a Project reference)
LibVLCSharp.WinForms : As stated here, this package only support .NET framework 4.0 and above, and .net core 3.0 and above. You will not be able to add this package in B, unless you replace your netstandard constraint and use multi-targetting instead. It will only work where WinForms is available.
LibVLCSharp can be referenced in project B without any issue. Since you're using .net standard, chances are you are also using the "SDK-style" csproj format and PackageReference. The dependency will then transitively be available in project A without adding it there.
If your point was having a player Form available in both .net framework and .net core, I'd recommend that you use multi targetting, by putting this in your B project:
<TargetFrameworks>net40;netcoreapp3.0</TargetFrameworks>
otherwise, if it's just for sharing non-ui code, you don't need the LibVLCSharp.WinForms dependency in B
Related
I have a .NET 6.0 C# class library project that contains platform-independent code (let's call this BusinessLogic). In my same solution, I would like to create a project for a WinUI 3 app that references this class library (let's call this WindowsApp). I would also like to create a class library specific to the Windows platform (so I can access the Windows.Storage namespace from within that class library, for example... let's call this WindowsOS).
I get an error when attempting to set this up. I have tried two techniques:
First technique
Create a .NET 6.0 C# class library WindowsOS.
In WindowsOS project, add reference to BusinessLogic. No problem.
In WindowsOS project, install NuGet packages Microsoft.Windows.SDK.BuildTools and Microsoft.WindowsAppSDK. This gives me an error about numeric comparisons on the target platform, similar to the one described in this GitHub issue. Afterwards, the project becomes unloadable in Visual Studio.
Second technique
Create a Class Library (Universal Windows) project WindowsOS.
In WindowsOS project, add reference to BusinessLogic. This gives me an error immediately, simply refusing to allow the reference to be added.
I suspect there appears to be some compatibility issue going on. I reviewed the Microsoft docs on .NET Standard versions, as well as this helpful StackOverflow question about .NET Core vs .NET Standard class libraries, and from what I can tell UWP may not be capable of referencing .NET class libraries.
My end goal is to create a WinUI 3 desktop app that references these cross-platform class libraries. My common code is contained in these libraries, and I may make an Android app or other platform app in a separate project that also references these same cross-platform class libraries. How do I do this?
EDIT: Here is a screenshot of the error from technique #1:
I figured out the answer. In the Visual Studio project properties (screenshot below), there is a Target OS property. That property defaults to (None).
Given the names of the projects in the question, set the property accordingly:
Set the property value to Windows in the WindowsOS project. This will give access to Windows-platform specific namespaces (such as Windows.Storage). WindowsOS can still have a project reference to BusinessLogic (and any .NET 6.0 C# library) as before.
No change necessary to the BusinessLogic project properties.
The WindowsApp (WinUI 3) project also requires no changes, and can reference BOTH the WindowsOS project (which now has a Target OS of Windows) AND the BusinessLogic project (which still has a Target OS property of (None).
Something to keep in mind: the WindowsApp project and the WindowsOS project will now both have Target OS version and Supported OS version properties. If you set these to different values in each project, you will get compiler warnings about a potential conflict (a user could install the app with a lower version of Windows, but that app then references the library which may require a higher version of Windows than the user has, for example). This does not matter if you are only using APIs supported in BOTH versions of Windows, but to be safe make sure these are consistent between your projects.
Okay, this is (or at least should be) a stupid question: How do I add a reference to a system assembly in .NET Core projects?
I have a .NET Core class library. If I right click on Dependencies, there is still a Add Reference... command, but it only allows me to add references to my other projects. There is now an SDK section, but right clicking there provides no option to add new references.
This was so straight forward before. I don't understand why this has changed or how I now add a reference to something like Microsoft.Win32.Registry. (My understanding is I need a NuGet package for this assembly, but my question still stands about adding system references.)
Even if your system contains this assembly it does not gurantee that other systems also contain it. .Net Core is about cross platform so I do not think there is this assembly in Linux system. So you should distribute not only your code but some of "system" dll as well. And it is easier to update only one nuget package for adding new functionality, bug-fixing, etc than update all framework.
I have created a system which loads dynamically a library and executes it's main class.
Everything works perfect, the problem I have is how to publish this DLL with all it's dependencies. As no executable project is referencing it I have to manually retrieve the dependencies: try to load the library, check the needed DLL's, go to the NuGet cache folder, copy the libraries, try again, check if it complains about more dependencies and so on until it has all the required libraries.
This is a true pain and I haven't found any information on how to do this, is it possible or am I stuck with this?
The library is a .net standard 2.0 library, I did this before with .net classic and the output folder always contained all the required libraries even the ones comming from a NuGet package, but with .net standard something has changed and now only libraries from referenced projects are being copied, no referenced NuGet package is being copied to the output folder.
Cheers.
Try:
dotnet publish
All the dependent libraries should be copied to the publish output folder.
At the time of writing, it looks like it's by design and there's quite some fuss and confusion about it, see logged issue on GitHub.
Moreover, when publishing a NuGet package for project A referencing project B,
B becomes a NuGet dependency in A; B's assemby is not included in A's NuGet package.
I deal with it by publishing my own NuGet packages.
I only don't like it to have a NuGet package for project B if that one is only relevant to be used with/by project A, as it will appear seperately in my NuGet feed.
TLDR: Convert your Class Library project into an Application, publish the application, and use application DLL as a library.
The long of it:
I tested this approach by deploying a full build with a plugin with many external dependencies to Ubuntu 18.04 and it ran perfectly.
Create a new project of type Console Application instead of Class Library. Put all your library code files into the Console Application and add the dependencies. Get rid of your original Class Library project (you don't need it anymore). Finally, publish the Console Application. You will get a DLL with all of the dependencies. You can use this DLL like any other DLL.
I suggest naming the console app project with "Library" on the end of it and adding a README just to document its not really an application even though the project is configured to build as one.
I would like to know how I can share c# source codes between two (or more) .NET Core projects (commandline projects!).
As far as I understand, I can not link to source files in different directories in xproj/project.json based projects. I noticed that it now seems to be recommended to create nuget packages for everything. But is it really necessary for me to setup a private repository and create a nuget package only to be able to share some common source units?
VS2015 contains a template for .NET Core library which may be suitable for building a shared lib. Is it possible to link this lib to a project without a nuget package?
.NET Core Library is an excellent solution for you.
Do it the same way as in standard C# solution - just create the project and reference this project or add a reference to DLL file.
You don't need to use a Nuget, for your own purpose. Nuget packages could be useful to distribute your dll outside.
Clarification:
I miss one point - I'm using VS2015, but I have included Class Library project in my solution, and I'm referencing by project, not by DLL file, and this works fine in ASP.Net Core.
I also have a different project, where referencing DLL file directly working fine, but this is the previous version of ASP.NET app (not Core) - seems NET Core doesn't support this way like as the previous version (yet?).
Sorry for confusing you, sometimes it's too many technologies ;)
So could you just include ClassLibrary project into solution with your project and refer it as a project?
I have achieved this by using source control to branch from my commonly used projects in each new solution, and again merging back to the master branch if I make any changes.
Alternatively, baring in mind that NuGet is only an archived collection of files, you could keep this NuGet package locally, or even create a Template for Visual Studio that has the common libraries by default.
There are a wide range of possibilities that are down to your preference, and current environment state (I.E: Able to setup Source Control, or a package repository).
I wanted to use two different version same library (OpenCVSharp 2.x and OpenCVSharp 3.x).
I downloaded those two packages both to the separate project (let's call it OCV2Wrapper and OCV3Wrapper) and reference both wrappers in my project. I had to renamed libraries from one package (2.x) and reference them manual because: Can we add 2 different versions of same package in NuGet. I read about external aliases and I used external alias in one of the wrappers (2.x in my case).
But I have some major problems:
My renamed libraries are not copied to the launch project build (that one which reference both wrappers), but is in build of the 2.x wrapper
It doesn't work because yet it says it cannot find a type from my 2.x wrapper even when I manually copy my renamed libraries from 2.x wrapper.
What is the correct approach for this scenario in C#?
I want to use both wrappers in solution because the 2.x version contains algorithms (SIFT and SURF) and 3.x version contains algorithms (Kaze and AKaze).
I can live that with both packages coming from somewhere other than NuGet, but I prefer that 3.x comes from NuGet and the 2.x version is manually configured.
As already stated, there is nothing wrong with referencing 2 different versions of a NuGet package, as long as it's in different Visual Studio Projects that those references are made.
But this is also where the easy part ends, but I think there are a few options left. Depending on your needs, I see the following options.
Create a post build step which registers the multi-versioned assemblies into the GAC. As long as each assembly have different assembly version, the CLR will pick up the right assembly from the GAC when needed.
Create a post build step which copies the different assemblies into a subfolder of your application bin folder like bin/package-v1 and bin/package-v2. Then you can, in your application, override the AssemblyResolve event as described here: https://msdn.microsoft.com/en-us/library/ff527268(v=vs.110).aspx. This will make it possible for you to load the assembly in the right version at the time of need.
If you don't want to play around with AssemblyResolve, then you can also modify your web/app.config to do assembly redirect/probing as described here: https://msdn.microsoft.com/en-us/library/4191fzwb(v=vs.110).aspx
Hope this helps a bit, so you don't have to modify third party source code next time.
OK so, I solve this by downloading whole sourcecode for 2.X wrapper version.
Renamed its namespace to ABCDEF2 where ABCDEF was original namespace. Build my own nuget package with my own key and... publish it to our private nuget server.
This is such a lame solution but there is no other way than manually downloading the original packages and reference it directly with different filename etc and you loose nuget advantages.