I have been given some criteria for a project. It MUST be constructed in a particular way. I know this isn't a great question but my C# is really rusty. The specification states:
Application namespaces should follow (but not be limited to) the below
[actual names changed]:
AnExample.Sample.Foo
AnExample.Sample.Foo.UnitTests
AnExample.Sample.Bar
AnExample.Sample.Bar.UnitTests
and that "each namespace should exist within its own assembly".
I'm a little confused- what is being asked for and how to achieve it? For each namespace to exist in it's "own assembly" does it have to be a separate project and referenced or is it a folder structure?
each namespace would have to be in its own project (.csproj)
within your projects, you could have whatever folder structure you wanted, as along as the namespace in the entire project is the same.
Basically, what they're asking you for is that each namespace is in its own separate file.
A project compiles to an assembly, which can be a .dll or an .exe. What they're saying is that each separate namespace should be in a separate project, so it compiles to a separate file. This is good for decoupling. You can then bring them all together using the Add Reference... button in VS.
Related
I was following a tutorial from Microsoft found at https://learn.microsoft.com/en-us/training/modules/create-razor-pages-aspnet-core/
At one point it instructs to add a folder under the root project called "Services". Within that folder is a file which needs to be accessed. Upon creating the project, another folder called "Models" was automatically created under the root folder.
I include the two lines at the top of another file:
using RazorPagesDoughnuts.Services; using RazorPagesDoughnuts.Models;
The Models statement works no problem. The Services statement generates the error. I have searched many resources and cannot find a solution.
I am using vscode 1.71.2 and .net 6.0
Screenshot of file structure and statements
The namespace provided in the file DoughnutService.cs is probably not correct. Change that to RazorPagesDoughnuts.Services and check.
In C# using statements are not based on file structure, but rather on namespaces. If there aren't any files with the statement namespace RazorPagesDoughnuts.Services in the project, then you will not be able to reference it in other files.
Make sure that DoughnutService.cs contains this namespace statement.
Hopefully an elementary question, but one to which I can't find an answer...
This Microsoft documentation leads me to believe that I need to add a using directive for my main project's namespace to my test class files, in order to be able to access the main project's members.
using MainProject;
namespace MainProject.Tests;
[TestClass]
public class UnitTests
{
...
}
However, when I do so, Visual Studio Code (with the Microsoft C# extension) tells me the MainProject import is unnecessary. And indeed, my unit tests manage to access the main project members without the using statement.
Both the main project and the test project exist in separate directories and have separate .csproj files. Both live inside a parent folder containing an .sln file to which each has been added. The test project's .csproj file has a reference to the main project's.
The main project's namespace is: MainProject
The test project's namespace is: MainProject.Tests
I have opted into global usings in the test project file, and there is a usings.cs file, which contains one line:
global using Microsoft.VisualStudio.TestTools.UnitTesting;
Where is the magic happening? (For example, is there a rule that the "child" namespace automatically "inherits" the types declared in the parent?)
Many thanks for your help.
A usising statement simple brings the namespace in scope for name resolution, it has nothing to do with directories or assemblies.
The namespace does the same thing, except it has a hierarchical basis and so isn’t as flexible.
In essence, there is no magic, you have misunderstood what is happening.
I found the official documentation explaining that namespace scopes "nest", and that the inner namespace has access to the members of the outer. Here it is:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/basic-concepts#77-scopes
(The second bullet point in section 7.7.1 describes the rule.)
When I last worked with C#, a long time ago, it was similar enough to Java to be virtually indistinguishable. But a lot has changed.
For example, I had forgotten that the Java-style namespace declarations are a recent addition to dotnet:
namespace MyCompany.MyProduct;
...
We used to have to do it like this:
namespace MyCompany
{
namespace MyProduct
{
...
}
}
Looking at it this way, it's easy to see why one might implicitly presume that the inner scope has access to the members of the outer, without having to read the rule from the language spec. If you're used to JavaScript scopes, for example, and your mental model of namespaces looks like the above, then the idea just seems natural.
However, if you're used to the way package imports work in Java, then this can seem very strange.
I have a problem understanding the difference between namespaces and assemblies.
So let's say that I make open Visual Studio, and I create a new project. I will name the project "Project A". The Solution Explorer will look like this:
Now, as far as I understood, the "Solution 'Project_A'(1 project)" is the assembly & "Project_A" that is right under it is the first namespace. Now, I know that I can add multiple "nested" namespaces with different classes. So I can make another class called X and then make a new folder in "Project_A", so a new namespace that will be called "MainClasses" and add the classes A & B there so that it would look like this:
So now, if I'm not wrong: I have the assembly "Project_A" that has the namespace "Project_A". The namespace "Project_A" includes a class called X & another namespace with classes A & B.
Now, if I go to "Solution 'Project_A'(1 project)" and I click on Add->New Project, I will make a new namespace with the name "Project_B", and add another class to the new namespace called Y, I will now have:
The assembly "Project_A" that will contain the namespace "Project_A" & "Project_B", and it will look like this:
Can somebody please correct me if I am wrong and tell me the right way. So what is the exact difference between namespaces & assemblies when working with c# in visual studio. Showing some screenshots would be the best, if you can do it, of course. Thank you
An assembly is an exe (executable) or a dll (dynamic link library) and it is a software primary "component" (not in the sense of OOP component or control). Sometimes named package.
What exactly is an Assembly in C# or .NET?
https://learn.microsoft.com/dotnet/standard/assembly/
A namespace is a code organization feature.
https://www.tutorialspoint.com/csharp/csharp_namespaces.htm
https://learn.microsoft.com/dotnet/csharp/programming-guide/namespaces/
An assembly that is like a partition can contains one or more namespaces that are like folders.
When an assembly is added to the references of the project, you can access to all its namespaces with the using directive at the beginning of the file or by specifying full access directly in the code.
Example
The assembly System.dll contains several namespaces like System and System.IO as well as System.Threading and so on.
using System.IO;
var lines = File.ReadAllLines(...);
Or:
var lines = System.IO.File.ReadAllLines(...);
...
These two concepts are not related. It's only by default that your initial namespace takes the name of your project.
By default each of your projects, contain the global namespace and your own. You can rename the default name of your namespace to anything you want without an issue.
The assembly:
Assemblies form the fundamental units of deployment, version control, reuse, activation scoping, and security permissions for .NET-based applications. An assembly is a collection of types and resources that are built to work together and form a logical unit of functionality. Assemblies take the form of executable (.exe) or dynamic link library (.dll) files, and are the building blocks of .NET applications. They provide the common language runtime with the information it needs to be aware of type implementations.
The namespace:
Namespaces have the following properties:
They organize large code projects.
They are delimited by using the . operator.
The using directive obviates the requirement to specify the name of the namespace for every class.
The global namespace is the "root" namespace: global::System will always refer to the .NET System namespace.
The namespace for the project is set in the project properties. It is by default set to the assembly name and class files inherit this name when created, but you can change to any name you like. If you add a folder and put a file in it, the folder name gets appended to the parent (for the first folder this is the assembly) namespace. Again you can change this to any arbitrary name.
I'm moving files in my project and I cannot find clear answer - is namespace connected with location of the file? Do I need to change namespace when moving files?
is namespace connected with location of the file?
Only by convention. It is not required, nor enforced by the compiler or runtime.
Note that in C#, you can nest namespaces, and can declare more than one namespace at any given level of nesting. Obviously only one declared namespace in a file can actually match the file's location. So it would not even be possible to require namespaces to match the file name, without abandoning those features in C#.
Do I need to change namespace when moving files?
No. See above.
You may be interested in related Stack Overflow Q&A's on the topic:
How to make the C# namespace work like Java Packages so they rename automatically when moving them?
How do I fix Visual Studio (2013) namespace collision when moving files
Should the folders in a solution match the namespace?
The first two relate to management of files and namespaces when changing the location of source files, while the third is more about generally accepted conventions.
I hit this weird namespace issue when adding my first 'Service Reference' to a client project in Visual Studio 2010.
If my project's default namespace uses two or more parts, e.g. MyCompany.MyApp then when adding a Service Reference a Reference.cs file is created containing the namespace MyCompany.MyApp.ServiceReferenceName with a lot of auto-gen code with fully qualified names, e.g. System.SerializableAttribute, System.Runtime.Serialization.DataContractAttribute.
The Reference.cs file will be full of compilation errors because the compiler starts treating the System namespace as sub member of the MyCompany.MyApp namespace. You get an awful lot of errors along the lines of:
The type or namespace name 'Runtime' does not exist in the namespace 'MyCompany.MyApp.System'...
If I amend the namespace at the top of the Reference.cs file to something simple, e.g. MyCompanyMyApp.ServiceRefernceName then the compiler behaves and recognises the System namespace references as decleration of .net's System namespace.
I'm using a different workaround for now as I really want to keep my multi-part namespaces. My current alternative is to append global:: in front of the System namespace references to force the complier to do the right thing. In fact, if the 'Add Service Reference' wizard uses T4 templates I may just amend those to embed my workaround at the source.
Questions
I'd really like to understand what's going on here and why a multi-part namespace causes this issue. Presumably there's more to namespaces than I thought. Secondly, would really like to work out a better solution than performing a global Find/Replace every time I add a Service Reference or mucking around with some T4 templates.
I found the answer here somewhat unclear, so I thought I would add this as an example (I would do it in the comments but it looks better here):
So I have this as my default namespace:
namespace RelatedData.Loader
But I also add a class named:
public class RelatedData
{
}
Because the class name matches a portion of the namespace when it generates your proxy with Add Service Reference it gets confused.
The answer here was to rename my class:
public class RelatedDataItem
Ahh well I found the cause eventually.
I'm working against a very large third party WCF API and ... one of their namespaces is LameCompany.System (!!) Carnage then ensues...
Arrrgghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
The lesson to learn here is when Visual Studio/.net compiler stops recognising the BCL's System namespace you have a namespace/type in your project called System. Find it, remove it, shoot the developer that created it.
I found that having a class name similar to your namespace causes this.
Try renaming your class name
I ran into a similar issue with VS2012 described by jabu.hlong and Simon Needham after minor changes in the client project that has the references to the WCF services after updating the reference to the services. I got lots of errors compiling the Reference.cs files generated and so on (the generated files of the XAML as well).
I have selected to reuse types from specific assemblies in my solution and got a similar problems with the namespaces.
The error I get is that the namespace of the reused assembly and the namespace of the generated types can not be found when used in the Reference.cs. Both namespaces have in common the first parts, as they are from the same solution. My namespaces in the solution are like appname.tier.technology.project. Both conflicting namespaces are Appname.Dto.Modulename (the reused assembly) and Appname.Client.Wpf.ServiceName (the namespace in the client project using the services for the generated types).
The problem arises after a minor change in the client project, when I created a new utility class in the namespace Appname.Client.Wpf.Appname. I choose that namespace because the Appname is also the name of a module in the client project. This seems to confuse the compiler and can not resolve both namespaces in the generated Reference.cs. After changing the namespace of the utility class to avoid using two identical parts in it and updating the service reference, the compiler errors in Reference.cs dissapears.
I tried different things (and tried different namespaces when adding the service reference), but nothing worked for me except this brute force fix - in my case it was OK but I am aware it's ugly (and needs to be repeated if you use "Update Reference" in the future):
Since the WCF service namespace is added to your default namespace, just search and replace all mentions of the newly added
MyNamespace.ServiceNamespace
with
ServiceNamespace
in the whole solution (use your own namespaces of course), including the auto-generated Reference.cs file.
Basically, the problem is a name conflict where one name is hiding another. A folder or class named "System" can do that, but if you also have a class with the same name as your project, you'll see the same thing. Sure, you can rename everything in the reference.cs, but it's probably better to rename your conflicting class.
I had folder in my project called "System" (yes, very stupid of me) and that caused some issues in the references.cs.
Renaming the folder (and the namespace), fixed the issue.
Here is how I solve this issue on VisualStudio 2017 trying to add a reference to a web service in a test project.
After trying adding the references, rebuilding, closing, reopening and spending some time on the issue, I noticed that VS had put the files it creates to reference the WS in a folder named "Connected Services".
I renamed the folder without the space then opened all the files in the folder and the csproj with a text editor, replaced all the occurrences of "Connected Services" to "ConnectedServices" and reopened the project.
I then added references to System.Runtime.Serialization and System.ServiceModel and everything now works fine.
This is a bug in Visual Studio (still is at version 2022). To fix, remove the namespace in the reference.cs file. So if your namespace is "myapplication" and your service is "myservice", you'll see myapplication.myservice in the reference.cs file. just delete "myapplication." everywhere and make sure it isn't auto-generated again (lest you have to re-delete everything).