I am currently converting a .Net Framework class library to a .Net Standard class library. In Framework we used app.config and had transform files to hold the environment specific data such as connection strings for the environment (Prod, Test, Dev).
I have scoured SO and Google for this answer but keep coming up empty. What is the best way to store and retrieve this data in a .Net Standard class library? At this point I don't care if I have a bit of code that populates properties based on my Build Settings or if I have a file sitting next to the DLL that houses this data. I'm just needing a way to connect to ServerA in dev and ServerB in prod.
I'll have either a .Net Core or .Net Framework project that references this DLL and asks this DLL for data but I want this library to house it's own DB connection, not passing it from the hundreds of apps calling it.
Turns out System.Configuration.ConfigurationManager was added back in .NETStandard 2.0.
Just pull it in from nuget and compile the .NETStandard 2.0 class library project.
Then, the library will work across projects using standard config files:
Net Core 2.0 projects use app.config
Web projects work from web.config
Console and Windows apps work with app.config
(This is of course assuming you're going to .NET Standard 2.0)
Then, here's a post I found that discusses how to use ConfigurationManager in case you need some examples.
Related
I have a Web API solution with several projects inside it. Tests, Services, Domain, Data and the API. The API project is the startup project. All of my EFCore references are in the Data project.
I am trying to run Scaffold-DbContext on the Data project however because it's not the startup project I'm getting the following error:
Your startup project 'APIProj' doesn't reference Microsoft.EntityFrameworkCore.Design. This package is required for the Entity Framework Core Tools to work. Ensure your startup project is correct, install the package, and try again.
The API project shouldn't know anything about EF Core so I don't want to just slap that reference in there and call it a day. Trying to do things better than they were... I also don't want to make anyone else who uses this to have to juggle startup projects. This should be simple.
How do I correctly point the Scaffold-DbContext command at a specific project regardless of what is the startup project.
Using the EF tools requires an executable project,
So you'd either need to add that assembly to the executable project like you're suggesting yourself, or you can add a dummy executable project.
See for ex;
Why is a dummy project required? As mentioned earlier, the tools have to execute application code at design time. To do that, they need to use the .NET Core runtime. When the EF Core model is in a project that targets .NET Core or .NET Framework, the EF Core tools borrow the runtime from the project. They can't do that if the EF Core model is in a .NET Standard class library. The .NET Standard is not an actual .NET implementation; it's a specification of a set of APIs that .NET implementations must support. Therefore .NET Standard is not sufficient for the EF Core tools to execute application code. The dummy project you create to use as startup project provides a concrete target platform into which the tools can load the .NET Standard class library.
https://learn.microsoft.com/en-us/ef/core/cli/dotnet#other-target-frameworks
In our own project structure we have the design reference included in our executable project aswell. However, now that i'm thinking about this, our app gets rather large, and running the EF commands forces a rebuild of the executable project, so this means it will completely rebuild my large app which takes a long time.
Therefore I recommend using a dummy project, like MSDN also recommends.
Edit;
I think in theory you could also make your data project an executable project, and reference that instead:
// ConsoleApp1
new MyConsoleApp2Class().Print();
// ConsoleApp2
namespace ConsoleApp2;
public class MyConsoleApp2Class
{
public void Print()
{
Console.WriteLine("Hello world.");
}
}
This does output the exe in your /bin however:
This depends on the framework of your data project, .net standard projects cannot become executables.
You can then use a Design time db context factory to help instantiate the db context for the tools (with the right sql connection string and so on):
https://learn.microsoft.com/en-us/ef/core/cli/dbcontext-creation?tabs=dotnet-core-cli#from-a-design-time-factory
That way you don't need your data project to contain a whole application, as described in https://learn.microsoft.com/en-us/ef/core/cli/dbcontext-creation?tabs=dotnet-core-cli#from-application-services
The advantages of using the executable project of your app is that you can maintain appsettings for 1 project, the other approaches you'd have to save the connectiong string in 2 places, or have some logic in the design time factory to fetch the right connection string or something along those lines.
But then again how often does your db connection string change? In most cases almost never.
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.
I'd really like to start using .NET Core and slowly migrate applications and libraries to it. However, I can't realistically upgrade my entire code base to use .NET Core and then go through the process of testing and deploying a plethora of applications in production.
As an example, if I create a new .NET Core application and try to reference one of my .NET Framework projects I get the following:
The following projects are not supported as references: -
Foobar.NetFramework has target frameworks that are incompatible with
targets in current project Foobar.NetCore.
Foobar.NetCore: .NETCoreApp,Version=v1.0
Foobar.NetFramework: .NETFramework,Version=v4.5
Is it possible to create a new .NET Core application and reference my existing .NET Framework libraries? If so, what's the process for doing that? I've spent hours going through Microsoft's documentation and searching their issues on GitHub, but I can't find anything official on how to achieve this or what their long-term vision is for this process.
Old question, but with the release of .NetStandard 2.0 and .netcore 2.0 and vs2017.3, the game has changed.
You can use the Full .NET Framework (TFM) with .NetCore 2.0, but how?
In Visual Studio 2017.3, you can reference the Full .NET Framework (any version) directly from within a .NetCore2 project.
You can build the .NetStandard2 class library and reference your TFM. Then reference your .NetStandard2 library from your .NetCore2 project.
For example, referencing json.net net45 from .NetStandard2.
Browse to the folder and select version net45 (not netstandard1.3)
See the dependency in the image below, no yellow warning as you see.
Even if a Nuget library is not ready to be ported to .Netstandard 2, you can use any API in the library that is compliant to net461.
Quoting for the .NET Core 2/Standard 2.0 announcement with links:
.NET Core 2.0 is able to freely reference libraries that have been built for .NET Framework up to version 4.6.1
However, some libraries may fail at run time if they try to use API methods that aren't available on .NET Core
Reference: .NET Core App target .NET framework 4.5.2 on Linux
A need to use third-party .NET libraries or NuGet packages not available for .NET Core
So only in cases where the libraries or NuGet packages use technologies that aren't available in .NET Standard/.NET Core, you need to use the .NET Framework.
Reference: Choosing between .NET Core and .NET Framework for server apps
You can now reference .NET Framework libraries from .NET Standard libraries using Visual Studio 2017 15.3. This feature helps you migrate .NET Framework code to .NET Standard or .NET Core over time (start with binaries and then move to source). It is also useful in the case that the source code is no longer accessible or is lost for a .NET Framework library, enabling it to be still be used in new scenarios.
Reference: Announcing .NET Core 2.0
Yes, we are currently attempting the same thing. The trick is to make sure that you are supporting the same .NET frameworks. Inside your project.json file, make sure the framework matches the framework of the project you wish to include. For example:
"frameworks": {
"net46": { --This line here <<<<
"dependencies": {
"DomainModel": {
"target": "project"
},
"Models": {
"target": "project"
}
}
}
},
FYI: You might need to change the framework of your .NET Core or your older projects to achieve this. .NET Core can be changed just by editing the project.json file as seen above. You can so the same in .NET projects by right clicking the project and opening properties. Change the framework level there.
Once you have matched the two project frameworks then you should be able to include them. Good Luck!
We delayed migrations as long as could as it seemed daunting as first. But we got an insistent client who wanted to migrate ASAP.
So we migrated their Fintech Web App developed on .NET Framework 4.8 Web Forms to .NET 6 Razor Page. Our team scoured though hundreds of online resources & spoke to Microsoft Tech Support before we started the project. Hope the high-level walkthrough of our journey help you plan your migrations.
Our .NET Framework Website consisted of 1 .NET Web Forms project and 12 Class Libraries.
Here is how we did it.
Refactored the .NET Framework 4.8 Web Forms code
We ensured that the Web Forms code behind did not have a single line of service or business logic code. When we did find some business logic code in the web forms code behind, we refactored it, by moving it to the class libraries.
Created new .NET Standard projects
We created a new .Standard 2.0 Class library project for every .NET Framework 4.8 Class Library. If the original project was called "FintechProjectName.StockMarketClient", we named the .NET standard project "FintechProjectName.StockMarketClient.Standard".
Copied all files from .NET framework to .NET standard
We copied all the class files from .NET framework to .NET standard projects. We then removed all the .NET framework class libraries from the solution and added references to the new class libraries. All projects compiled on the 1st try itself and all our test cases too passed with minor changes.
Create new .NET 6 Web App Project
We created a new .NET 6 Web App Project. We had to entirely redo the front-end as there is no direct path for migrating Web Forms to Razor Pages. This was the only project which took us about 1 month to migrate.
Reference .NET standard class libraries in the new .NET 6 website
We copied all the .NET Standard libraries to this new solution containing the Razor Pages web site. Added the references and got it to work.
Move from .NET Standard to .NET 6 class libraries
Once the new website was up and running, with all test cases passed, we did the last step in the process which was the simplest. Created .NET 6 class library projects for each of the .NET standard libraries and named the projects appropriately. Copied all class files from .NET standard projects to their corresponding .NET 6 projects. Then we removed the .NET Standard libraries and added references to the new class libraries.
Overall project timelines were about a month and a half, most of it spend on Razor Pages implementation using the same html design.
Note:
If you are using any 3rd party library which does not have a .NET standard or .NET 5 version, then you are out of luck. You will need to find a replacement nuget package and recode your application to use this new library.
In my case with .net6 referencing framework 4.8 library ( both winforms), the trick seems to be to add the reference to the framework dll as a shared reference.
Our client has complained about the count of .dll files in the .NET Core app we made for them. Their dissatisfaction persists even after we explained that this is how .NET Core works.
Now I do understand their position completely, my jaw dropped too when I created the package for the first time:
Note how small the scroll bar is. Most of the library names begin with Microsoft. or System. - those that don't are libraries that I use and installed manually.
So the question is: is there anything I can do about this to make our client happy? Aren't the System.* libraries already installed on their machine as a part of .NET Core runtime?
We're targeting .NET Core 1.0 at this moment.
You can create two types of deployments for .NET Core applications:
Framework-dependent deployment
Self-contained deployment
It seems you need Framework-dependent deployments (FDD).
Portable (FDD) application is similar to the traditional .NET Framework application. In this case, a certain version of the .NET Core Framework (also known as shared framework, .NET Core Runtime, redist) should be on the target computer, and when the host starts, the process will load Core CLR, Core FX from the frame folder.
Artifacts of the same Portable Application for different versions of the .NET Core platform
You can see what Directory structure of published ASP.NET Core apps should be
To run Portable applications, at least one .NET Core Runtime (shared framework) must be installed on the target machine. The framework files (s) are stored in the C:\Program Files\dotnet\shared folder.
Core is designed to do this. In old .NET Framework apps, there's a runtime dependency on .NET Framework, i.e. the end-user must have the version of the .NET Framework the application targets installed on the machine as well. Core takes a different approach; it brings everything it needs into the build. As a result, you can drop this folder on any machine, no matter how it's set up and "run" it. (Now technically, you need dotnet.exe in order to run it, unless you build as an executable, but that's just to run the main app DLL.)
Anyways, this is by design, and it's actually much better when you think about it. Your app has just the dependencies it actually needs and nothing else. You don't have to worry about external things like what version of .NET Framework is installed, etc.
That said, I know there's some third-party applications (mostly commercial) that can enable you to "bundle" DLLs or even package up everything into a single executable. However, I'm not sure how compatible, if at all, these are with .NET Core. Still, if your client insists, I'd just see if you can find some tool that does that and essentially "hide" the DLLs.
Microsoft says it's platform neutral these days, so I'm trying to build on Mac and Linux only with VS Code and deploy to Azure. Why? It's mainly to prove that I can.
Our project has several parts which include a couple of different websites, a Web API, er API and a few other bits. On my Mac I've built a .Net Core Class Library with a load of objects in. Command line, dotnet build, DLL out, no problem.
I want to put that DLL on the Linux machine where the MVC website is being built - the objects forming the models part of that site hopefully. I cannot figure out how to get the website project to reference my DLL and use the objects.
I had assumed I copy it to the other machine, place it in the bin folder of the site being developed and reference it in the Dependencies section of the site's project.json. Nope. I saw a few articles that said .Net Core only works with NuGet and it had to be a package. Is that really true?
I've found and read (if not entirely understood) everything you could imagine on sharing between .net core and .net framework. This is a core-only project so not applicable. Frankly I'm lost, and something called .Net Standard has just rolled into my field of vision.
So instead of copying the DLL, use dotnet pack to build a nuget package on your Mac, and copy that to your Linux machine instead. Put it in a directory that you configure as a local nuget repository (no server or anything required) and you're away.
I agree it's not as straightforward as a reference to a DLL, but it's not too bad. Note that you'll need to version the package appropriately, so that the tool system can detect when it's changed.