The unity documentation recommend to use namespaces to organize your code, avoid extended class name, and make more maintainable code.
ControlerCameraAction becomes Controleurs.Cameras.Action and CameraAction becomes Cameras.Action.
However in Unity editor you can't see your namespaces, only the last class name, and this can be confusing since some class have now same name.
Editor shows now Action and Action
So how to use namespaces in Unity?
Am I doing something wrong?
So how to use namespaces in Unity ?
Like you did, basically. Namespaces are used in code, not in the editor. The main problem of Unity is the way that scripts are treated. Scripts get compiled internally into debuggable IL-Code.
But in the editor itself, they are always named by their filenames, which are forced to be the same as the class name.
This is the reason you don't see your whole type-name (namespace + classname), but always the classname alone.
Am i doing something wrong ?
No, you aren't. As far as I remember, there is no way to display the classname instead of the filename in the editor, since the displayed data is determined by the meta-files that Unity generates.
So tl;dr:
You are doing it right and there is no way to display the namespaces in the Editor.
I'd suggest you should sort your scripts into folders and use the AddComponentMenu-Attribute to organize your code physically according to your namespaces. This is the same pattern that is used by Microsoft.
Easy way is to think in namespace how file folder. You assign your desired name avoiding similar name to systems and unity namespace. Each namespace inside another namespace is similar to navigate inside a folder inside another folder.
Ussually this start with your company name or your plugin name:
namespace mycompany_name
{
namespace myplugin_name
{
}
}
or
namespace myplugin_name
{
//part name i.e. Networking, Utils, Database or similar ramification
namespace myplugin_part_name
{
}
}
Later you reference to it in another script with "using":
using mycompany_name.myplugin_name
The unity documentation recommend to use namespaces to organize your
code, avoid extended class name, and make more maintainable code.
Yes !
ControlerCameraAction becomes Controleurs.Cameras.Action and
CameraAction becomes Cameras.Action.
Yes, and no.
The idea behind namespaces is organization not just simple use this feature called namespaces. And that organization should follow a logic. If every class has a different namespace then you will have to import as many namespaces as classes that you will use in your code.
You can think in terms of 'modules' or maybe see if a layered architecture can be useful for you.
If you have ControllerCameraAction and CameraAction, you can a.- use the namespace Cameras for both (then you will have Cameras.CameraAction and Cameras.ControllerCameraAction) , b.- if you have a layered architecture (like MVP, MVVM, or some more DomainDesign Driven, etc.) you can have namespaces using the layer name and the module. (then you will have something like Presentation.Cameras.ControllerCameraAction, Domain.Cameras.CameraAction and this can help you to follow an Onion architecture).
The syntax for namespaces are like this:
namespace Domain.Cameras
{
public class CameraAction
{
}
}
And you use them with using directive
using Domain.Cameras;
namespace Presentation.Cameras
{
public class ControllerCameraAction
{
private CameraAction cameraAction;
...
}
}
More about namespaces here!
By default all classes that don't have an explicit namespace belong to global namespace, so even when you are not writing any namespace you are using one.
Unity will not make any difference between namespaces, this is more a c# characteristic. And it helps with organization, separation of concerns principle, and avoiding name conflicts too, but in the last instance, your class names should still be representative and clear enough to understand what that class does. If you see Camera.cs and Camera.cs it's really hard to see what class does what. If you open those files and see the namespace/code/folder where they are that will help, but the idea is save those extra seconds/cognitive load and just be more explicit with your names.
As a complement here you can see another interesting discussion about namespaces use.
Related
Unfortunately, due to issues that are frustratingly out of my control, I'm forced to use components with namespaces which I cannot change. Because of the way they have structured them, it's causing collisions in the generated code-behind.
Again, unfortunately, I do not have access to the code which defines these namespaces so they cannot be changed. Down-voting this does not help anyone, especially without a reason/explanation. Also, I've also tried demonstrating the issue to the owners explaining why this is a very bad design, but I've been told for other reasons, changing them is not an option, so I'm forced to find a work-around.
Here's a simplified example to illustrate the issue. Consider a solution with two projects, a 'Core' library, and the consuming application:
Items in 'Core' Library
ModelA (Namespace: SomeFeature.Core.Models)
ModelB (Namespace: SomeFeature.Core.Models)
**Items in 'ConsumingApp' (References 'Core') **
MainWindow (Namespace: ConsumingApp.SomeFeature)
TestControl (Namespace: SomeFeature.Controls)
The cause of the collision can be explained in three steps:
SomeFeature is both the root of one namespace, and a child of another
TestControl is defined as being in the rooted version of the namespace (same as the library), not the one MainWindow is in.
Code-generation ends up placing the generated variables for those XAML elements in the namespace scope of MainWindow, not that matching what's actually in the XAML.
Now if these were manually-defined variables in non-generated code-behind, dealing with this is easy. By simply adding the prefix global:: it 'roots' the namespace you're typing, thus removing all ambiguity.
namespace ConsumingApp.SomeFeature{
public partial class MainWindow{
// Note the 'global::' prefix
global::SomeFeature.Controls.TestControl MainTestControl { get; set; }
}
}
The above will ensure that it always resolves relative to the global SomeFeature namespace and never the nested ConsumerApp.SomeFeature namespace. Pretty straight forward.
However, the auto-generated code-behind from the XAML parser doesn't include that global:: prefix, so in the generated code, you actually get this:
namespace ConsumingApp.SomeFeature{
public partial class MainWindow{
// Note: without the 'global::' prefix, this resolves to
// 'ConsumingApp.SomeFeature.Controls.TestControl'
// which doesn't actually exist, causing the mentioned issue.
SomeFeature.Controls.TestControl MainTestControl { get; set; }
}
}
Which results in this error:
Error CS0234 The type or namespace name 'Controls' does not exist in the namespace 'ConsumingApp.SomeFeature' (are you missing an assembly reference?)
As noted in the code comments, this is because it's not looking for this class path...
SomeFeature.Controls.TestControl
but rather this one:
ConsumingApp.SomeFeature.Controls.TestControl
which doesn't exist, ergo the error.
The fix would be to somehow get the auto-generated code to explicitly output the global:: but I don't know how to do that, or even if it can be done.
Things I've tried:
Arguing for them to change their namespaces! (I lost!)
Explicitly referencing the assembly in the XAML import:
Defining aliases in the non-generated code-behind
Searching for aliases in the XAML world (not found)
Avoiding naming the element, and instead manually searching for the control via other properties. (Horrible, but this does work!)
So is there anything that can be done here to get the code-generator to include the 'global::' prefix, or is there another way to do this?
I'm new and I don't know other way to explain so I posted my screenshot of project! Please help me to fix these errors... SCREENSHOT
You seem to be having a lot of problems with references and namespaces use.
First of all, you do not have a Card class defined. You only have a CardModel. Replace Card for CardModel and you will be good to go. Also, it seems you do not have a namespace declared on your class. Declare a namespace so you can use other classes in the same namespace (tipically the project name).
Second, if you are trying to use clases in another folder, you probably have to add the reference with the using keyword.
You're missing probably several using directives. Every class you write should be inside a 'namespace' You declare it after your using directives but before you start writing your classes, like this:
namespace WebShop.CardModel {
public class CardModel {
public string InsertCard(Card card){
And when you are working in the cardModel, unless Card is defined in the same namespace, you need:
using WebShop.Card;
Or whatever namespace you put Card in, that's what is throwing probably 99% of your errors, it is definitely the cause of all but one of the ones in the errors we can see in your screenshot.
I have the following two files:
IGlobalApiProvider.cs
using System.Collections.Generic;
using Vert.Slack;
namespace Vert.Interfaces
{
public interface IGlobalApiProvider
{
List<Im> ImList();
}
}
And the corresponding implementation: SlackApi.cs
using System.Collections.Generic;
using Vert.Interfaces;
namespace Vert.Slack
{
public class SlackApi : IGlobalApiProvider
{
public List<Im> ImList()
{
...
}
}
}
Now, Intellisense is telling me that when I use IM in IGlobalApiProvider it's resolving to Im, which is defined in a file named RtmStart.cs which has no namespace declaration. When I use IM in SlackApi.cs, it's resolving to Vert.Slack.Im which is defined in the Vert.Slack namespace in a file named Im.cs. The weird behavior alerted me to the redundant definition, so I removed it and things are working fine.
However, I'm confused about why Visual Studio behaved differently in these two ways. I can tell something was scanning for the class names in a different pattern in the two situations. I can also tell that being used in the same namespace vs being used in a class that uses the namespace seems to be the trigger. What I don't know is what mechanism controls the logic behind this behavior.
Can anyone shed light on this?
Everything you see is contained in Vert.dll, which consists of one project, Vert.csproj
Link to the four files mentioned in this post as they existed at the time of writing.
This has to do with the difference between the global and Vert.Slack namespaces.
The compiler looks for the most explicit namespace with the proper class defined.
In this example, when the compiler looks for the definition of Im in IGlobalInterfaceProvider.cs, there is no namespace defined (or used) in this file that contains the class, but Im is also defined in this file - which is declared in the global namespace.
When the compiler looks for the definition of Im in SlackApi.cs, Im is found in the explicit Vert.Slack namespace, and utilizes that class.
The answer here is a similar topic and may provide more insight.
This may be related to the fact that your namespaces are in the wrong place ;-)
http://www.stylecop.com/docs/SA1200.html
This answer here gives a good explanation: Should 'using' statements be inside or outside the namespace?
I'm working on a C# library (let's just call it "Foo" for the sake of this question). It has some needs very similar to standard .NET needs: for example, it provides some drawing services, and some conversion services.
For the sake of familiarity and users of the library being able to guess what things are called, I'd like to follow the .NET standard, and name these parts of the library Foo.Drawing and Foo.Convert (and so on). But I'm finding that in actual use, this causes pain. People almost always have "using System;" at the top of each file, and when using this library, they want to have "using Foo;" as well. But now they have two Drawing and two Convert modules, and hilarity ensues.
For example, now instead of just using Drawing.Color for a parameter or variable type, you have to explicitly spell out System.Drawing.Color, or the compiler complains that Foo.Drawing doesn't have a Color type. Similarly, you want to use a standard Convert.ToInt32, you have to say System.Convert.ToInt32, even though you're already using System, because otherwise it finds Foo.Convert and fails to find ToInt32.
I understand why all this is as it is, but I'm still new to the C# community, so I don't know which is the most standard solution:
Leave it this way, and expect users to use fully-qualified names where necessary?
Rename the conflicting modules to something else (maybe Foo.Graphics instead of Foo.Drawing, and Foo.Conversion instead of Foo.Convert)?
Use some prefix on the standard names (Foo.FDrawing and Foo.FConvert)?
Something else?
Any advice from you more experienced C# gurus will be appreciated!
You can use namespace aliasing :
using System;
using FConvert = Foo.Convert;
public class Bar
{
public void Test()
{
var a = Convert.ToInt32("1");
var b = FConvert.ToInt32("1");
}
}
One of the main usage of namespaces is to avoid name clashing.
It means that namespaces allow developers to create types with identical names, as long as the belong to different namespaces.
A library usually have at least a root namespace, and possibly nested namespaces that logically groups the related types.
Name your types as you wish, as long as the names are meaningful and represent what the type really are. A client of your library expects a type named Animal to represent an Animal, not something else. The same applies for naming namespaces.
However, avoid at all cost the names from System, since it will be really annoying for your library clients (as you described) to deal with conflicting names all over the place.
A common way to deal with conflicting namesapces inside a class is to use namespace aliasing:
using FooConvert = Foo.Convert;
using BarConvert = Bar.Convert;
I'm working on a project in which I use Depency Injection. When registering a set of interfaces and classes, I need to point out the namespaces at which those interfaces and classes are located.
I don't like providing string constants though, mainly because it hurts refactorability. I don't like taking one of the interfaces/classes and get it's namespace either. For example:
typeof(FoodStore.Fruits.IApple).Namespace
because it looks odd having all these arbitrary type names lingering around (why choose IApple over IOrange?), only to distract from the actual point of the code. There's simply no sensible rule which type to pick.
I came up with the following solution.
Put a namespace anchor class in every namespace I need to reference:
namespace FoodStore.Fruits
{
/// <summary>
/// Serves as a type based reference to the namespace this class
/// is located in.
/// </summary>
public sealed class _NamespaceAnchor
{
}
}
Now I can use:
typeof(FoodStore.Fruits._NamespaceAnchor).Namespace
Whenever I refactor the namespace, I don't have to worry about the DI registrations.
Although this solution satisfies the question's requirements, I'm still not happy because now I have these sort of ugly empty classes hang around. I can't make them internal because - obviously - the references span across assemblies.
My question is: does anyone know of a more elegant solution?
No, there isn't anything better - namespaces aren't really first class concepts in the CLR, as far as I'm aware. Yes, Type allows you to ask it for a namespace - but namespaces are really for humans rather than the VM.
Note that unlike in Java, there's no access control at the namespace level. I haven't checked, but I suspect there's no particular metadata token for a namespace.
I can't think of anything about namespaces which would affect the CLR at execution time. Clearly they affect language compilers - but again, that's for the benefit of humans, so that we can organise types hierarchically and avoid specifying that hierarchy at every step.
I'd be concerned here that the namespace (which is really just part of the class name) has functional meaning in your application. If a later maintenance engineer moves some classes around, they may inadvertently break the injection system without realizing it. The error won't become apparent until runtime and could take a while to track down.
In this case, I would prefer a more explicit opt-in, such as using attributes. Here's one possibility:
public class TestInterfaceAttribute : Attribute { }
public interface IMyInjectableService { }
[TestInterface]
public class TestService : IMyInjectableService { }
public class RealService : IMyInjectableService { }
That said, most DI frameworks already either have some form of export meta-data (to help resolve the correct dependency for your particular use case) or are structured in a way that you define the dependency resolutions explicitly.