I have a library which is .NET standard version. This library will be used both .NET app and .NET Core apps. I want to use IConfiguration for .NET Core apps in my library but .NET apps throw an exception.
I need to check version or determine the application if .NET Core or .NET framework? I have tried get appsettings.json file to determine app type but getting root path different both .NET and .NET Core apps.
When I tried to get framework version of app it gives me library's version.
How can I distinguish which type of application it is? How can I achieve this?
There are several ways to solve your problem:
try to use more common parameters for your methods that requires string's, int's or custom classes instead. Is it really necessary to add a framework specific class or function or is there a better option?
You can use a multi-target configuration for your library which then requires #if NET45 and #elif NETSTANDARD2_0 code everywhere you have to use different logic for different frameworks. This could lead to not very well readable code.
Use two libraries, one for .NET Core apps (e.g. based on .NET Standard 2.1) and the other for .NET Framework (e.g. .NET FW 4.8). The .cs files from the .NET Standard library can then also be used in the .NET 4.8 library (if compatible features have been used). The .cs files can be selected e.g. in VS via "context menu > add existing element". When confirming the selected file(s), expand the dropdown option under "Add" and select "Add as Link". This way the file only needs to be maintained once (changes are applied in both libraries). Framework-specific files can then be added individually in the respective library, not as a link. Here's a good article about it.
These are just some examples, there might be of course other or better solutions to it.
Personally I would try to use independent arguments for my methods, if this is not possible I prefer the custom library solution for each framework version.
Related
I am working on API versioning on .Net Core 3.1. The issue is that we are consuming an external nuget package that will apply different versions on different API versions. For example, for API Version 1.0, I need to use V2.0 of this nuget package; for API Version 2.0, I need to use V3.0 of this nuget package.
So if I use the strategy this way: https://dev.to/99darshan/restful-web-api-versioning-with-asp-net-core-1e8g by spliting the controller classes in the same project, then it would force all of my API versions with the same nuget package versions.
I was wondering what's the better way to do API versioning in my scenario?
As long the features you are using are functionally compatible (typically by source code), then the NuGet package versions do not need to match. You did not specifically say, but I get the impression you are defining API versions by applying attributes and that is the only surface area used by the code and libraries that define the corresponding controllers.
You're describing a typical setup for plug-in or composition based API applications. Assuming that is correct, then the NuGet package version is only interesting to the host application (e.g. the hosting server code). The host application that runs the server must use a version of the NuGet package that is greater than or equal to the highest version used by any of the other referenced assemblies. The rest is handled by .NET, not NuGet. Modern .NET projects enable automatic binding redirects; typically without any developer configuration. This means that if your controller libraries are an array of say version 1.0, 2.0, and 3.0 and the host references 3.0, then all libraries ultimately use 3.0 at runtime. The only caveat to this is that all libraries must target the same runtime. For example, you cannot make a mix of full .NET Framework and .NET 5.0 (formerly .NET Core) work together. As long as the runtimes are aligned, you should not have any problem getting everything aligned; regardless, of NuGet package or assembly version.
There are also, at least, two other solutions to this problem.
Use Conventions - API Versioning provides a fluent interface for defining API versions by convention. It was designed to solve the exact problems of applying API version metadata to controllers defined in another library. This configuration would likely be defined in the host application. You can also define your conventions so you don't have to define every version individually. The VersionByNamespaceConvention uses this approach to derive a single API version by the containing .NET namespace.
Use Custom Metadata - Contrary to popular belief, API Versioning does not care about attributes. It provides some attributes as a simple, out-of-the-box way to apply metadata, but it's not a hard requirement. It only cares about IApiVersionProvider. This means that you can easily roll your own attributes and then plug it into API Versioning by implementing IApiVersionProvider or IControllerConvention. This would allow you to create metadata library, with .NET Standard if necessary, that will likely never change and you can subsequently add to the versioning configuration.
#2 is a more advanced scenario. I'm not aware of any existing examples that would demonstrate all of that end-to-end, but if you choose that path and have questions, I can push you in the right direction.
I have a .NET Core project that needs to receive a string which determines which authentication logic to use and then use it.
The authentication logic needs to be a DLL that sits in a directory and implements an interface.
We should have the option to add more DLLs that implement the interface to the directory, without compiling the project.
.NET Framework has a perfect solution for that - MEF (Managed Extensibility Framework).
Unfortunately, .NET Core only partially supports MEF (Doesn't support DirectoryCatalog, which is what allows scanning a directory and loading assemblies)
Is there a similar/better way to achieve this in .NET Core?
Since in .NET Framework I added the reference through the Assemblies tab, when I tried the same in .NET Core it wasn't there. Also I read a false/outdated article that claims it's not supported in .NET Core - I got the impression that it's not possible.
I figured I better look for a NuGet package that gives an alternative and found out you just had to install the NuGet for System.DirectoryCatalog.Composition and it works.
Here's the article:
https://www.tutorialspoint.com/dotnet_core/dotnet_core_managed_extensibility_framework.htm#:~:text=MEF%20is%20a%20library%20for,and%20is%20available%20wherever%20the%20.
Only System.Composition is ported, and System.ComponentModel.Composition is not available yet. This means, we don’t have the catalogs which can load types from assemblies in a directory.
If anyone is stumbling on this, there is another way to add plugin capability to a .NET 5+ application.
This means using AssemblyLoadContext, which is better documented than MEF for .NET Core/.NET5+
I have a library built using .netstandard framework and say the version of that library is 1.1.2.
Now i have a .NET Core application built using that library(version:1.1.2).
If i upgrade the library version to 1.1.3, without recompiling is there a way to run the same .NET Core application against 1.1.3?
In .NET Framework we have bindingRedirect which can be set in the App.Config file and the .NET Framework application built using library version 1.1.2 can run against a library with version 1.1.3/1.1.1 as well without recompiling.Is there a similar thing for .NET Core as well?
If i upgrade the library version to 1.1.3, without recompiling is there a way to run the same .NET Core application against 1.1.3?
Yes - just replace the dependency with the updated version and it should just work (assuming of course that the updated dependency hasn't changed its public API from version 1.1.2).
.NET Core behaves differently to Framework in that its runtime (CoreCLR) attempts to resolve dependencies by looking for versions that are the same or higher than the application was built against.
.NET Framework's CLR looks for the specific version of the dependency that the application was built against - forwards compatibility is one of the reasons why the binding redirect mechanism had to be added.
Core's (arguably more logical) approach means that it doesn't support the concept of binding redirects at all - because it doesn't need them.
In .NET Framework we have bindingRedirect which can be set in the App.Config file and the .NET Framework application built using library version 1.1.2 can run against a library with version 1.1.3/1.1.1 as well without recompiling.Is there a similar thing for .NET Core as well?
No - as stated above, binding redirects aren't supported in Core and the dependency resolution algorithm only consider versions of the same or newer.
I can't find any documentation as to why there is no built-in support for older versions, but I suspect it's got a lot to do with the fact that such a scenario is both unlikely, and that supporting it ends up effectively causing the type of DLL hell that .NET was supposed to avoid.
.NET Core provides the AssemblyLoadContext class, which you can extend to provide your own implementation of an assembly-loading algorithm to handle your specific case. For example, you could write an AssemblyLoadContext that uses binding redirect rules from an app.config file to load your dependencies (whether you should do something like this is another story).
I've added a new Class Library (Package) project to my solution. It's my first experience with a .NET Core (or whatever I'm using, still confused)
My class library contains two references: .NET Framework 4.5.1 and .NET Platform 5.4
I'm trying to import some code from a sample project that uses IPrincipal. For some reason it's saying that it doesn't exist on namespace "System.Security" altohugh I can get it trough intellisense.
What's wrong with my project settings?
The new feature of .NET Core and Class Library (Package) is that it targets multiple platform and will compile into multiple assemblies which get automatically packaged into a nuget package.
When your class library targets multiple targets, it will compile to all of them. So if a certain library is only available on full .NET framework but not on .NET Core or other target framework, then you may receive intellisense if your editor is set to .NET 4.5. More information can be found in my other recent answer.
You can switch back and forth with the pull down menu on top left of the coding window, show in the screenshot below.
If you do not want to target a certain framework, you have to remove it's moniker from the project.json file or use preprocessor directives to write platform specific code or libraries/replacements.
.NET Core is heavily modularized and most of only the core modules are referenced in the default project and if you need additional one you need to reference them within the dotnet5.x section.
Basically you have multiple places with "dependencies" in your project.json, a global one where you can add dependencies which are available on all targeted frameworks and one within each "frameworks" section for each of the targets only.
Though the other answer covers some basic concepts, it would require some attention on which classes are available and which are not.
Microsoft temporarily host a web site at http://packagesearch.azurewebsites.net to assist.
If you can find a suitable package for RC1 from there, then you can add it to your project.json file. If not, you will have to conditional compile it to a desktop profile or use other alternatives.
I installed Visual Studio 2015 RC to try out the ASP.Net vNext templates. In the "Web" section, I have noticed a console application that appears as
I decided I would mess around with it and I found some interesting points:
The default template does not specify Main() as static.
Many assemblies such as System.CodeDom and System.Net are not available.
Many methods such as System.Console.ReadKey cannot be used.
What are these vNext console applications? Why the restrictions and what are the uses of them?
Answers
What is a vNext console application?
It's a console application that runs within the new .NET runtime environment (DNX).
Why the restrictions and what are the uses of them?
The restrictions occur because you are targeting .NET Core (dnxcore50) instead of (or in addition to) the full .NET Framework (dnx451.) The use of those restrictions, as far as I know, is to allow cross-compatibility with a lot of different operating systems. That is, .NET Core has less functionality than the full framework does, because it is easier to be compatible with many systems that way. Overtime, those restrictions may fall away as more in made fully cross platform.
The default template does not specify Main() as static.
DNX comes with Microsoft.Framework.ApplicationHost. This default application host "knows how to find a public void Main method. This is the entry point used to set up the ASP.NET hosting layer..." It also still knows how to find the traditional static void Main method. An advantage of an instance Main method is that it lets us ask the runtime environment to inject services into our application.
Many assemblies such as System.CodeDom and System.Net are not available. Many methods such as System.Console.ReadKey cannot be used.
System.Console.ReadKey is available in dnx451 but not in dnxcore50. That's also true for System.Net the last time I checked. So, if you want to use those, make sure to target dnx451 instead of dnxcore50.
Want to remove the restrictions? Just delete the dnxcore50 entry from your project.json file. Then you'll only be targeting the full framework without restrictions.
See Also
https://msdn.microsoft.com/en-us/magazine/dn913182.aspx
'Console' does not contain a definition for 'ReadKey' in asp.net 5 console App
Using System.Net.Mail in ASP NET MVC 6 project
Those console applications are leveraging the new .NET execution environment (DNX, previously KRE). It includes a new project system and allows you to target different versions of the CLR.
One of those versions is CoreCLR which is a slim version of .NET. This version is modular and its libraries are distributed as a bunch of NuGet packages. You may need to include some additional packages when targeting .NET Core (dependencies section on your project.json file).
Nevertheless, some of the limitations may arise from the fact that not all the APIs are already migrated to .NET Core or from the fact that they won't be, since the API surface is smaller on .NET Core.
I'm slowly going through the new runtime and will update this post with relevant references.
Microsoft.Framework.Runtime.Sources.EntryPointExecutor->TryGetEntryPoint()
Has the piece of code that is picking out the Program class and its Main function