As of lately I'm using quite some code generation, usually in combination with partial classes. Basically the setup is as follows:
Partial class containing generated code. Some of this code will call partial methods. The code is re-generated a lot of time. The code generator is in some cases a custom tool.
Partial methods are manually implemented in a separate file.
The problem is that when I'm using Intellisense features like "generate method", they are for some reason generated in the file containing the generated code. Obviously I don't want that.
My question is: Is it possible to generate some hint that tells Intellisense it shouldn't touch certain 'cs' files (but instead the other partial class)?
Update
In retrospect I should have noted that I'm using a custom tool to generate the code. It's not a EF or a simple transformation; there's quite a bit of logic involved in the code generation. Also, it generates a complete namespace and class structure with partial classes. The 'root namespace' is found by extracting it from the csproj file and then using the folder structure to figure out the absolute namespace (it's similar to how Linq2sql does this).
The answer suggested by xanatos (thanks!) works: intellisense sorts its operation on the name, then alphabetically sorts on the name and then picks the first item in the list. This means that you can generate a zzzz.foo.cs which (albeit a bit ugly) will work just fine. I've just ran some experiments and found out that the feature find all references returns the order that VS appears to use. As it turns out, it works like this:
Say you have a custom tool that works on the filename foo.bar and transforms it into foo.cs. The custom tool will generate the content as string and pass it back to Visual studio (that's just how custom tools work...). The result will be in a file called foo.cs.
Now, I was quite surprised to found that Intellisense does not sort it as foo.cs but rather as foo.bar\foo.cs. In other words: regardless of how you name the 'cs' output in your custom tool, you have to rename the base file foo.bar to something like zoo.bar.
While that might be a workaround, I'm hesistant to accept it as the answer, because I would have to give files in my project strange names (names have meaning...). Also, some of my custom tools have dependencies on their filenames, so that will also get broken...
Therefore, I'm still open for suggestions on how to fix this properly.
From a simple test I've done in VS2013, it seems that Visual Studio 2013 adds the method to the "first" file he finds in the Solution Explorer. So you could simply add a .something.cs to your file-name, like MyClass.generated.cs vs MyClass.cs. Be aware that the VS2013 seems to be using the "full path", with path ordering based on name. So:
Z\MyClass.cs
comes after
MyClass.generated.cs
(and Intellisense will put code in MyClass.generated.cs) even while in the Solution Explorer all the folders are ordered first.
Full example:
A\MyClass.gen3.cs
MyClass.gen2.cs
Z\MyClass.gen1.cs
This should be the order as "seen" by the Intellisense, so it will put the new classes in A\MyClass.gen3.cs.
Assuming you're talking about the EF, I always change the template file (.tt) so the filename of the auto-generated file is [classname].model.cs. This means my partial file, which by convention is called [classname].cs is alphabetically first and always seems to get picked for auto-generation.
All you have to do is find/replace all the:
fileManager.StartNewFile(entity.Name + ".cs");
With:
fileManager.StartNewFile(entity.Name + ".model.cs");
There should be 3.
This has other benefits like auto-generated files are clearly marked in the filename.
I still have no idea why they didn't do this in the first place.
If you're not talking about the EF, the same trick of using the filename to order them should work.
Related
This question is on behalf of one of my team members: I am a developer in charge of writing the documentation for our product. I have written a tool in C# to output our assembly in markdown style files. In order to facilitate the ease of use for our classes, I wanted to implement a way of linking the class type and property constructs to any MSDN documentation available publicly. For the most part, this was accomplished simply by using the namespace of the class like so:
msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol(v=vs.110).aspx
However, I ran into some problems when looking at classes with generic type arguments and properties. They seem to be generated in a special manner that looks like a hashed string, like so:
msdn.microsoft.com/en-us/library/b682ts2x(v=vs.110).aspx
The “b682ts2x” part of the URL is the part that is different.
I would like to know if there is any way I can get in touch with someone who knows how these links are generated, and if there is a way to generate the same exact URL portion (that is, b682ts2x) for any class property using only reflection.
As an alternative approach you could use the same syntax that the F1 help is using when you highlight a class name for example.
As mentioned in Visual Studio intercepting F1 help command
msdn.microsoft.com/query/dev11.query?
appId=Dev11IDEF1&
l=EN-US&
k=k(width);
k(vs.csseditor);
k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.0);
k(DevLang-CSS)&
rd=true
The "k" parameter above is contains the help context inside visual
studio. Help context contains both "keywords" (text strings) and
"attributes" (name/value pairs) which various windows inside Visual
Studio use to tell the IDE about what the user is doing right now.
For example here is one for System.Net.HttpHttpClient.
https://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k(System.Net.Http.HttpClient);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)&rd=true
Notably when I pressed F1 when highlighting "HttpClient" it assumed I meant ServiceClient.HttpClient so be careful to provide the namespace.
I would like to generate some C# code based on existing code.
More precisely I need some mappers for existing enums as well as converters, unit-tests for them.
It would be a longer discussion why I've generate this code rather than go for a generic approach, but considering that I would like to generate some classes based on some enumeration types, what options would I have?
I am just thinking about visual studio extensions, some templates or maybe resharper addins but so far I haven't done anything like this...
I would appreciate any input of those of you who had previous experience with such a task.
ReSharper supports Live Templates as a means of generating code. You can create whatever code you like in there, with editable or linked hotspots to provide customisation points (e.g. current file name, class name, time, new guids, suggested variable names, etc). You can generate code snippets in existing files, surround existing code, or create new files. ReSharper 8 also introduces support for multi-file templates, creating more than one file at a time.
However, ReSharper's templates don't support things like loops - you can't loop over an XML file and generate a class member for each element, for example. T4 would be a better solution for that.
Reegenerator supports generating code from existing code. You can create a code generator and then attach it to the file that contains the enum type. The generator will be executed everytime the file is saved.
The code generator are given access to the Visual Studio DTE Object, which will give you the code structure through CodeElement classes (CodeClass, CodeAttribute, etc). From there you can either generate a separate partial file through a T4-like template, or simply manipulate the code directly using the DTE EditPoint.
I added two custom classes to my project, namely "AutoSizeGrid" and "AutoSizeGridEditable"
Both derive from DataGridView, but that's probably neither here nor there.
But where they are is seemingly somewhat of a conundrum.
My project builds and runs fine; however, when inspecting it with Resharper, it gives me a "Constraints Violation" for both of these, saying: "Namespace does not correspond to file location, should be: ''
Do I need to change them like so, from, e.g.:
class AutoSizeGrid : DataGridView
...to:
class <Name of my Solution>.AutoSizeGrid : DataGridView
?
I'd rather not, as I don't know if this would force me to delete the prior DGV-derived components from my forms and replace them with the recompiled versions; that would be a pain in the donkey.
As ElVieejo says, it is not necessary to change it if the code compiles. ReSharper (and other code quality tools) recommend you keep namespaces in sync with file paths because that is the Microsoft convention. Namespaces are extremely helpful for keeping code organized, especially as projects/applications get larger, so it's good to have some clear rules and follow them, but they are for readability and separation of concerns, not syntactical correctness.
I'm starting a project which is broken up over multiple VS projects and I was planning on having separate testing projects for each of the projects, so I'd have a solution like this:
Project1
Project1.Test
Project2
Project2.Test
There are some internal classes which I want to have tested. So I used Visual Studio 2008 (SP1) to generate the test stubs in my test project and added the InternalsVisibleTo. But I get a red squiggly line under the internal class. If I compile I get a successful build, and looking at the test method the red squiggles are gone.
But if I tough the file the squiggles come back and I have no intellisense on the internal class.
The internal is within Project1 and the test is within Project1.Test. For completeness I decided to do the exact same manner of generating the test method but this time into Project2.Test, and this time it's shown to be completely working. I don't get red squiggles, I get intellisense, everything.
I've tried deleting Project1.Test and recreating the test method, everything I can think of, but no matter what I do I can't get the internal to be completely visible within its paired Test project, only in the one which is designed to be for another project.
It's doing my nut that it's not working!
I've seen this too, especially when using strong names. To be honest, I didn't get excited; as long as it compiles and tests correctly, I can live with the odd glitch. For example, if you get one build problem, I've seen it complain that it can't find the other (internal) methods - but a clean build shows no errors. Again, I'm not to bothered by this... (maybe I'm too forgiving?).
In particular, it is only rarely that I need to use an internal type/member in the tests (most of the time I'll try to test via the public API); so the lack of 100% reliable intellisense isn't usually a big problem. I already know the type/member I am looking for (copy/paste ;-p).
Sure, it would be nice if it was fixed, but if I was the budget manager, I could probably live with it and focus on other features first.
Could you be using a string constant or something other than the exact literal stirng (without concatenation) in your InternalsVisibleTo attribute? We had the habit of using a string constant to define it, and that works fine for everything except intellisense. Replace by pasting as a simple string and it works.
Deleting your .suo file (same folder as your solution file) might help as well.
It might be a problem with IntelliSense DB file. Try to delete it and have VS try and rebuild the DB.
To do this close the solution and delete (all?) .ncb files. To be on the safe side, just rename them to something like .nc4 or whatever. Reopen the solution and rebuild it. Let me know if it works.
EDIT: Apparently, ncb files are only for C++ projects. I don't know where the IntelliSense DB for C# projects are, nor could I find out. If I were you, I would still try to find a way to reset the DB.
Asaf
Should the folders in a solution match the namespace?
In one of my teams projects, we have a class library that has many sub-folders in the project.
Project Name and Namespace: MyCompany.Project.Section.
Within this project, there are several folders that match the namespace section:
Folder Vehicles has classes in the MyCompany.Project.Section.Vehicles namespace
Folder Clothing has classes in theMyCompany.Project.Section.Clothing namespace
etc.
Inside this same project, is another rogue folder
Folder BusinessObjects has classes in the MyCompany.Project.Section namespace
There are a few cases like this where folders are made for "organizational convenience".
My question is: What's the standard? In class libraries do the folders usually match the namespace structure or is it a mixed bag?
Also, note that if you use the built-in templates to add classes to a folder, it will by default be put in a namespace that reflects the folder hierarchy.
The classes will be easier to find and that alone should be reasons good enough.
The rules we follow are:
Project/assembly name is the same as the root namespace, except for the .dll ending
Only exception to the above rule is a project with a .Core ending, the .Core is stripped off
Folders equals namespaces
One type per file (class, struct, enum, delegate, etc.) makes it easy to find the right file
No.
I've tried both methods on small and large projects, both with single (me) and a team of developers.
I found the simplest and most productive route was to have a single namespace per project and all classes go into that namespace. You are then free to put the class files into whatever project folders you want. There is no messing about adding using statements at the top of files all the time as there is just a single namespace.
It is important to organize source files into folders and in my opinion that's all folders should be used for. Requiring that these folders also map to namespaces is unnecessary, creates more work, and I found was actually harmful to organization because the added burden encourages disorganization.
Take this FxCop warning for example:
CA1020: Avoid namespaces with few types
cause: A namespace other than the global namespace contains fewer than five types
https://msdn.microsoft.com/en-gb/library/ms182130.aspx
This warning encourages the dumping of new files into a generic Project.General folder, or even the project root until you have four similar classes to justify creating a new folder. Will that ever happen?
Finding Files
The accepted answer says "The classes will be easier to find and that alone should be reasons good enough."
I suspect the answer is referring to having multiple namespaces in a project which don't map to the folder structure, rather than what I am suggesting which is a project with a single namespace.
In any case while you can't determine which folder a class file is in from the namespace, you can find it by using Go To Definition or the search solution explorer box in Visual Studio. Also this isn't really a big issue in my opinion. I don't expend even 0.1% of my development time on the problem of finding files to justify optimizing it.
Name clashes
Sure creating multiple namespaces allows project to have two classes with the same name. But is that really a good thing? Is it perhaps easier to just disallow that from being possible? Allowing two classes with the same name creates a more complex situation where 90% of the time things work a certain way and then suddenly you find you have a special case. Say you have two Rectangle classes defined in separate namespaces:
class Project1.Image.Rectangle
class Project1.Window.Rectangle
It's possible to hit an issue that a source file needs to include both namespaces. Now you have to write out the full namespace everywhere in that file:
var rectangle = new Project1.Window.Rectangle();
Or mess about with some nasty using statement:
using Rectangle = Project1.Window.Rectangle;
With a single namespace in your project you are forced to come up with different, and I'd argue more descriptive, names like this:
class Project1.ImageRectangle
class Project1.WindowRectangle
And usage is the same everywhere, you don't have to deal with a special case when a file uses both types.
using statements
using Project1.General;
using Project1.Image;
using Project1.Window;
using Project1.Window.Controls;
using Project1.Shapes;
using Project1.Input;
using Project1.Data;
vs
using Project1;
The ease of not having to add namespaces all the time while writing code. It's not the time it takes really, it's the break in flow of having to do it and just filling up files with lots of using statements - for what? Is it worth it?
Changing project folder structure
If folders are mapped to namespaces then the project folder path is effectively hard-coded into each source file. This means any rename or move of a file or folder in the project requires actual file contents to change. Both the namespace declaration of files in that folder and using statements in a whole bunch of other files that reference classes in that folder. While the changes themselves are trivial with tooling, it usually results in a large commit consisting of many files whose classes haven't even changed.
With a single namespace in the project you can change project folder structure however you want without any source files themselves being modified.
Visual Studio automatically maps the namespace of a new file to the project folder it's created in
Unfortunate, but I find the hassle of correcting the namespace is less than the hassle of dealing with them. Also I've got into the habit of copy pasting an existing file rather than using Add->New.
Intellisense and Object Browser
The biggest benefit in my opinion of using multiple namespaces in large projects is having extra organization when viewing classes in any tooling that displays classes in a namespaces hierarchy. Even documentation. Obviously having just one namespace in the project results in all classes being displayed in a single list rather than broken into categories. However personally I've never been stumped or delayed because of a lack of this so I don't find it a big enough benefit to justify multiple namespaces.
Although if I were writing a large public class library then I would probably use multiple namespaces in the project so that the assembly looked neat in the tooling and documentation.
I think the standard, within .NET, is to try to do it when possible, but not to create unnecessarily deep structures just to adhere to it as a hard rule. None of my projects follow the namespace == structure rule 100% of the time, sometimes its just cleaner/better to break out from such rules.
In Java you don't have a choice. I'd call that a classic case of what works in theory vs what works in practice.
#lassevk: I agree with these rules, and have one more to add.
When I have nested classes, I still split them out, one per file. Like this:
// ----- Foo.cs
partial class Foo
{
// Foo implementation here
}
and
// ----- Foo.Bar.cs
partial class Foo
{
class Bar
{
// Foo.Bar implementation here
}
}
I'd say yes.
First, it will be easier to find the actual code files by following down the namespaces (say, when somebody e-mails you a naked exception call stack). If you let your folders go out of sync with namespaces, finding files in big codebases becomes getting tiring.
Second, VS will generate new classes you create in folders with the same namespace of its parent folder structure. If you decide to swim against this, it will be just one more plumbing job to do daily when adding new files.
Of course, this goes without saying that one should be conservative about how deep xis folder/namespace hierarchy goes.
Yes they should, only leads to confusion otherwise.
What's the standard?
There is no official standard but conventionally the folder-to-namespace mapping pattern is most widely used.
In class libraries do the folders usually match the namespace
structure or is it a mixed bag?
Yes, in most class libraries the folders match the namespace for organizational ease.