.Net Core: Using Directive Without Adding Package? - asp.net-core

For example this happened to me when I added configuration (IConfigurationRoot) in the Startup.cs file, to be able to access appsettings.json file which has a connection string.
So the first time I write IConfigurationRoot it is obviously marked as not recognized, so I put my mouse over it and expand the Visual Studio suggestions from the light bulb, which are:
using Microsoft.Extension.Configuration:
Microsoft.Extension.Configuration.IConfigurationRoot
Generate Type
Add package Microsoft.Extension.Configuration.Abstractions 1.1.0
So if I pick "using Microsoft.Extensions.Configuration",a using directive is added at the top of my file and VS recognices IConfigurationRoot, everything works fine. But checking the References in my project, this library was not added to it:
No Reference Added
So if instead of picking the using directive, I pick "Add package Microsoft.Extensions.Configuration.Abstractions 1.1.0", Visual Studio also adds the using directive but additionally it adds a new Reference:
Reference Added
I'm not understanding why this happens, why adding the using directive (first suggestion) works fine, is it because the reference is already contained in another library?, if so, why should I add the package individually?. Is it better to add it individually?, what happens if I do, am I adding a reference to the same library twice?
Thanks in advance.

...is it because the reference is already contained in another library?
Yes, look under the Microsoft.Extensions.Configuration.FileExtensions or Microsoft.Extensions.Configuration.Json and you eventually get to the Abstractions package.
If so, why should I add the package individually?
There is no need. The light bulb tooling might not quite up to speed with the whole package dependency stuff.
Is it better to add it individually?
Not really, but if your ever removed some of those base package then adding it individually from Nuget would ensure that it would remain.
What happens if I do, am I adding a reference to the same library twice?
In an indirect way, yes, but there's no harm. The Dependency tree view drills down into each layer of dependencies. You will see lots of "duplicates" if start expanding those nodes.

Related

MVC - Application Assembly

Question:
If I have multiple projects in one solution is it still considered a single assembly?
Background Information:
I'm aware the 'MyApplication/Properties/AssemblyInfo.cs' file exists. Further, I confirmed that when I:
Add a project to the solution.
Appropriately reference the newly added project.
Lastly, Build the solution.
The 'MyApplication/Properties/AssemblyInfo.cs' file has not changed. This leaves me to believe, and please correct me if I'm wrong that I'll have met the demand.
Thank you
No.
Each project is compiled into one assembly in your case. The assemblyinfo.cs file (for each project) should not change at all when you compile anything. Also, that file's name is not important at all; it's the global attributes inside it that cause various properties of the assembly being created to be set. That file's name and location are simply a convention.

Setting MSBuild 'Condition' attribute via Visual Studio extension

I have a C# project which is built in a few different configurations. Some of the source files should be always included, and some only in certain configurations. So far I've been doing this with #if ... #endif around the entire files, but I was hoping to create a small extension to do this a nicer way.
I've created an extension that adds an item to files' context menus, but I can't find any way to set the Condition attribute on the item node in the project file.
I've looked at the Properties collection of the EnvDTE.ProjectItem interface, but can't see anything useful there (except BuildAction... I'll come back to that).
Then I tried getting an IVsBuildPropertyStorage on the item and calling SetItemAttribute(). This does add information to the project file, but as a child element like this:
<ItemGroup>
<Compile Include="Program.cs">
<Condition>%27%24%28Configuration%29%27==%27Debug%27</Condition>
</Compile>
</ItemGroup>
when what I was trying to achieve was:
<ItemGroup>
<Compile Include="Program.cs" Condition="'$(Configuration)'=='Debug'" />
</ItemGroup>
There's also an IVsBuildPropertyStorage.SetPropertyValue() but that adds a similar child element to a PropertyGroup section near the top, not to the item node.
I've looked at 'Project Subtypes/Flavors', but that looks like it's just going to get me another IVsBuildPropertyStorage, which doesn't seem to be useful. They do look capable of a lot of complex things, but documentation on the subject appears to be minimal and vague.
I've seen some posts describing how to use the MSBuild assemblies to directly load and manipulate the project file, but I'm not sure when is safe to do that without confusing Visual Studio and potentially losing changes, since VS prompts to reload when it detects changes to the project file.
As a last idea, I thought about manipulating the BuildAction property between Compile and None, but that sounds like it could be a lot of work for my extension to maintain correctly, keeping it in sync with every time the user switches configurations in the IDE for example.
Is there anyone with any experience with this kind of thing that has any advice to offer me, or should I give up hope and stick with manually adding #if directives everywhere?
You may like to explore the MSBuild option you mentioned.
You don't actually have to load the MSBuild project from file, because Visual Studio gives you a way of accessing the MSBuild project directly, i.e.:
string projectPath = projectItem.ContainingProject.FullName;
MsBuildProject project = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(projectPath);
var compileItems = project.GetItems("Compile");
From there you can locate your specific items and potentially add the condition attribute, though I haven't tried this step myself (if this doesn't work, you might have to try modifying the project elements under the project.Xml property instead).
You can then call project.Save(), which shouldn't trigger the "Reload project?" dialog because of the way the MsBuild project instance is linked to the Visual Studio project hierarchy.
However, you may like to force Visual Studio to reload the project anyway, because if you switch build configurations (e.g. between Debug and Release), the MSBuild engine may not re-evaluate your item conditions during build. The code to do this programmatically can be found here:
How do I programmatically refresh/reload a VS project after modifying the underlying file?
Unfortunately I never got the time to persue the original goal of creating an extension for doing this, however I did achieve what I needed using the suggestion by lex-li: using separate project files per configuration.
Since the project files can all reside in the same directory, it's easy to simply use the 'Include/Exclude from project' context menu item in the solution explorer to choose which files are included. There's also no need for file linking this way, which I'd tried before and found very time-consuming to manage.
Partial Methods are also worth looking at, if you have similar needs. They allow you to define the signature of a method in one place, but optionally implement it elsewhere. If you don't implement it, no call is generated by the compiler.
With respect to the original idea of the extension, I suspect the answer by Daniel Nolan was heading in the right direction, but unfortunately I didn't get to try it out.

What DLL file do I need to add to my solution to use DbSet?

I am trying to use the generic DbSet class. I have tried adding the following references so far to my solution because the MSDN documentation states that DbSet lives inside System.Data.Entity:
However, as shown below I still cannot add a reference to System.Data.Entity, the only suggestion intellisense has is EntityClient which does not contain DbSet:
Resharper/Intellisense is not giving me any other suggestions of namespaces I could possibly add.
I have tried cleaning and rebuilding my solution, and I am using the .Net Framework 4 full version (not the client version).
I have tried using NuGet to search for EntityFramework and have found one result which I have added to no avail as is show below:
What DLL file do I need to add to my solution to add a reference to System.Data.Entity and use the DbSet class?
Thanks
The same MSDN reference page that you mention says that you need to reference EntityFramework.dll in your project.
Note that namespaces and assemblies are not the same thing. The following statement is a little over-simplified, but you can think of namespaces as residing inside (or becoming available by referencing) an assembly.
So, once you've referenced the assembly, you will still need the using System.Data.Entity; directive.

Using a new version of a user control WITHOUT removing and replace each one?

BACKGROUND:
I'm self-taught in VB.net, having been a VB6 developer for years. I'm now out of the field but I'm making a forms app that I need for my new business. I am using VB2008 Express, and I'll upgrade to later versions when necessary. Because I am self-taught I mostly work from examples and there's a lot about .NET I don't understand.
SITUATION:
I've built a Usercontrol. (A custom datetimepicker which I call "datebox"). Then in my application project, I add it to the toolox, then plunk it on a form. It works great so I use it many times in my project, each time with a various properties. No problem so far.
THE PROBLEM:
Oopsie... Now I realize I want my usercontrol to behave a little differently. I modify its project, keeping it backward-compatible with regard to properties and events. Then I rebuild the control.
Ad you might expect, I find that the project that uses the control is still referencing the old version, which it has placed into its own \debug\ folder. Originally, I had added the control to the toolbox from my "DateBox\bin\Release" folder.
My current process to update my project for the new version is very time-consuming... First I delete every datebox object from every form, then I remove the reference to the datebox control, then I remove it from the toolbox and put it back, (not sure if that step is needed) then I place all of my databox objects back where they belong, (which automatically adds it to the project references) and set each of the properties of each datebox object.
THE SOLUTION????:
Surely, Microsoft must be smarter than I am, so it's GOTTA be possible to just rebuild the user control, then just "suck in the new version" without having to remove and replace each one and reset their properties as desired.
Can I get some guidance on how this can be done?
Assuming that the UserControl is not part of the solution, the approach that we use to to create an Assemblies folder on disk somewhere in the solution hieararchy.
Any external assemblies that we use in any of the solution projects are then copied into this directory and the assemblies are added directly as references. This allows us to use different versions of the assemblies in different projects and not have to worry about accidental updates to either assemblies that we are responsible for or others.
If we need to use the controls at design time, we remove any previous controls from the toolbox and then drag the file(s) from the assemblies folders into the toolbox to ensure we get the right versions.

Is AssemblyInfo.cpp necessary?

I want to remove AssemblyInfo.cpp, because of some metadata errors that sometimes come up.
Is AssemblyInfo.cpp useful for anything? Or can it be removed without any problem?
I've discovered one distinction for this file: it has to do with values reported under calls to Assembly.GetReferencedAssemblies. I was working on tracking version numbers of our binaries from our SVN repository by embedding the revision numbers into them. Initially I too was updating AssemblyInfo.cpp and found nothing reported in the file property details tab for the binary. It seemed this file did nothing for me in terms of updating those details, which was not the case with similar updates to a csproj's AssemblyInfo.cs. Why the difference right?
Now in one such csproj we happen to reference a vcxproj and that csproj dumps to a log the versions of all its referenced assemblies using the .NET Assembly.GetReferencedAssemblies method. What I discovered was that the number that was being reported in that log was not the vcxproj's version as given by the VS_VERSIONINFO resource I added (which does get the version details into the file properties details tab). Instead the number reported was actually matching that defined in the AssemblyInfo.cpp.
So for vcxproj files it looks like VS_VERSIONINFO is capable of updating the contents you find under the file properties details tab but AssemblyInfo.cpp is capable of exposing the version to GetReferencedAssemblies. In C# these two areas of reporting seem to be unified. Maybe there's a way to direct AssemblyInfo.cpp to propagate into the file details in some fashion, but what I'm going to wind up doing is duplicating the build info to both locations in a prebuild step. Maybe someone can find a better approach.
So far I never had the AssemblyInfo.cpp in my managed c++ dlls, so I don't think it is necessary.
(I just added the file to have version information for my c++ dlls).
Why not just fix the errors? On that note, what errors are you getting?
This file provides information such as a version number which is definitely needed in order to use the assembly you have built.