How can I perform "Go To Definition" programmatically in Visual Studio? - c#

Given a string that represents a specific class/field/property (eg MyNameSpace.MyClass or System.String.Length), how can I programmatically cause Visual Studio to go to that class/field/property (ie, make Visual Studio do the same thing that would happen if I was to type in the reference in the code editor and then hit F12)?

You probably need to do the following.
Get the global IVsObjectManager2 interface (implemented by the SVsObjectManager object)
Call IVsObjectManager2.FindLibrary to get the C# library, and cast the result to IVsSimpleLibrary2.
Call IVsSimpleLibrary2.GetList2 with the correct VSOBSEARCHCRITERIA2 in order to locate the symbol within the projects for your solution.
If the resulting IVsSimpleObjectList2 has GetItemCount()==1, and CanGoToSource with VSOBJGOTOSRCTYPE.GS_DEFINITION returns pfOK==true, use the GoToSource method to jump to the source.
Otherwise, rather than jumping to the source, simply display the possible options to the user. You will be able to use the IVsFindSymbol interface (implemented by the SVsObjectSearch object) to for this.

Related

C# Visual Studio 2013 suppress 'Class is never instantiated'

I have a web api project which accepts HttpPost communications.
The controller's methods always accepting a single validated object.
For example:
public sealed class NumbersRequest
{
[NumberOne]
public string Number1 { get; set; }
[NumberTwo]
public string Number2 { get; set; }
}
Since I never declare NumbersRequest req = new NumbersRequest() and they only serve as a request object, Im getting the
class is never instantiated
How can I suppress the warning? (its more like a green underline..)
Maybe something with annontations?
Thanks.
This looks like a ReSharper warning and as such you can ask ReSharper to be silent about these things.
You can either configure ReSharper to stop complaining about this overall, you do this simply by hitting Alt+Enter on the squiggly in question and use the bottom menu item that usually allows you to configure the inspection severity.
You can opt to save this in your global settings, which means it will affect every project you open from now on, or you can save it to a team-shared settings file which you can then check into source control alongside your project, to make it only count for this one solution.
Now, if you want to keep the warning overall but ask it to stop complaining about one or more particular types, methods, properties or the likes, you can use the attributes that ReSharper provides.
You have several ways of bringing these attributes into your project:
Add a reference to the Nuget package "JetBrains ReSharper annotations"
Use the options dialog for ReSharper and find the page where it allows you to grab a copy of the source for those attributes onto the clipboard, then simply paste this into a file in your project.
Define just the one or two attributes you want, even in your own namespace (which you then have to tell ReSharper about)
The recommended way is option 1, use the nuget package.
Assuming you now have the attributes available you can use either PublicAPIAttribute or the UsedImplicitlyAttribute.
Either one should suffice but they may have different connotations. Since you're flagging objects being transferred to or from clients I would go with the PublicAPIAttribute first.
Since you say in a comment that the PublicAPIAttribute didn't work but UsedImplicitlyAttribute did then I guess they do have different meanings.

Quickest way to declare a field and constructor-inject it

Using Visual Studio 2015 Enterprise with Resharper Ultimate.
I find myself often needing to declare a new field, and then have it assigned by a constructor argument. As far as I know, the quickest way is to:
Navigate up to the top of the file where the field declarations are
Declare the field:
private readonly NameOfType _nameOfInstance;
alt-enter on the field name, "Initialize field from constructor"
navigate back to where I needed the object and continue
This isn't too onerous, I just find that I do it so many times a day, I'm left wondering whether there's a faster way. Is there a Resharper / VS function / plugin where I can press a key, specify a type, and have it do all of those steps for me? The _nameOfInstance is nearly always just _nameOfType, and it's always private readonly and constructor-injected, so it would be good to reduce this bit of busy-work from my day.
With ReSharper, you can place the cursor in (or highlight) the parameter in the constructor and use CTRL+R, CTRL+F to create a field from it.
You can type an unused symbol name in your code and hit Alt+Enter on it to automatically create a field (or even better, type the new field name, followed by .field, which will act like a template/snippet and automatically create a field with that name at the top of the class). You can then Alt+Enter on the new field and select "initialise from constructor" to wire it up in the constructor. This will move you out of the current method, though. ReSharper doesn't offer a way around that, but you can use the "Navigate back" command (Ctrl+Minus) to jump back to the method you were working on.

How to specify order of debugger visualizers in Visual Studio

I've been working on a debugger visualizer for Visual Studio for some time and while the actual visualizer works fine. The problem is that it always places itself at the top of the visualizer list when examining a variable which really annoys some of the users who rather have Text as the top one (since the top one is also default when opening VS).
I can't find any support for this on DialogDebuggerVisualizer or DebuggerVisualizerAttribute which were my first thoughts so I've been scouring SO/MSDN/Google for information on how to affect the sort order of the visualizers (preferably to put mine last in the list) but to no avail.
Below is how I register my visualizer, it then just shows a form based on the value that is being visualized.
using Microsoft.VisualStudio.DebuggerVisualizers;
[assembly: System.Diagnostics.DebuggerVisualizer(
typeof(Shorthand.VSAddins.JsonVisualizer.JsonVisualizer),
typeof(VisualizerObjectSource),
Target = typeof(string),
Description = "Json Visualizer")]
namespace Shorthand.VSAddins.JsonVisualizer
{
public class JsonVisualizer : DialogDebuggerVisualizer
{
protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
{
var json = objectProvider.GetObject() as string;
var form = new VisualizerForm { Json = json };
windowService.ShowDialog(form);
}
}
}
Does anyone know if it is possible to affect the order of the visualizers or should I just let it be?
I don't think there is a solution. But there is a workaround:
Define your own Text Visualizer and put appropriate DebuggerVisualizer attribute before the attribute of your JsonVisualizer. The result will be that string will be readable by default and Json Visualizer can be chosen. A window with a multi-line textbox is not too much work.
It is probably not even necessary to write visualizer. It should be possible to use internal one but I don't know its name (Which class is used for "Text Visualizer"?).
It will always appear first, by design. The under the hood cast has found the best match for the variable it is reflecting on.
however, you could do either of two things. You could make the visualizer only appear when the sting contains ':'
Or you could use reflection to reorder the visualisers by adding them to the end of the collection in the order you want, then removing the originals from the collection.
For the latter you will most likely have to change the collection from readonly to writable. Via reflection.
There is no reliable source to draw on other than your will to succeed.
I guess that VS 'under the hood' can distinguish between type of string and type of xml quite easily, but Xml is just a string too, so a key question here would be, how does VS tell the difference between the two?
Could you dissect the VS XML visualizer to see how it works (even if you have to use reflector on the DLL to do it, you might get to see the method that works it out)

Visual Studio Visualizer

To make this clear, I'm using .net 3.5
I'm currently creating an Visual Studio Visualizer in order to be able to see the values of individual rules in a WF RuleSet. Everything is ok, but now I need to do the following.
Let's say I have a rule which is "this.Age > 50" and one then action as MessageBox.Show("Bigger than 50") and one else action as MessageBox.Show("Less than 50")
I need to be able to select the rule "this.Age > 50" and evaluate it as true or false. Or I need to select part of the rule, eg. "this.Age" and evaluate it to let's say 70.
This last bit is working. I'm getting the object in which the RuleSet executes and getting the fileds and try to find one field named Age and if I do find, I get it's value, on the event of not finding the field I then look at properties. This is working.
The problem is evaluating "this.Age > 50". Of course, I could do a parser in this case and evaluate it, but the problem is then I would have to evaluate "this.Age > 50", "this.Age < 50"... I guess you understand the problem. And of course I also want to evaluate for example, "this.GetCurrentAge()", in which GetCurrentAge() is a method in the class represented by the object in which context the RuleSet executes.
I've thought I could try to inject a method at runtime into the object I currently have and which is instantiated. This way, I could create something as simples as
public string EvaluationMethod()
{
return (this.Age > 50).ToString();
}
in this case, I would at runtime build this method and inject it in the current instance of object.
The problem is that I can't seem to find a way to inject code into the current instance of the object. I can only find examples on how to create new classes at runtime, but nothing about only creating a method and inject it.
Can someone please help, or give any other idea?
Thanks

No reference to project item created through AddFromTemplate() returned

In a Visual Studio Add-In that successfully creates a form, but gives me no reference back to the EnvDTE's prjItem instance.
Here's the piece of code that adds the form to the project:
string templatePath = solution.GetProjectItemTemplate("Form.zip", "csproj");
ProjectItem prjItem = project.ProjectItems.AddFromTemplate(templatePath, "myForm.cs");
Obs.: 'solution' is an EnvDTE80.Solution2 object.
Of cource I can get the reference by other ways, like proj.ProjectItems.Item([index]) (doing a loop and checking for names), but that's not how I want to do it, and I need this reference in orther to add controls to this form.
Am I doing something wrong?
Just found a comment on MSDN:
AddFromTemplate always returns a NULL
value
At one time, this was true. But
with later versions of Visual Studio,
which included the ability to add
multiple items from a single template,
the return value for this method could
not return multiple items. So it now
returns a NULL value in all instances.
This is due to the contraint that the
COM signature for this particular
method cannot be changed without
breaking a lot of code already in use.
Consequently, if you need the
ProjectItem interface of the item just
added via the AddFromTemplate call,
you can either iterate through the
ProjectItems collection, or you can
create a ProjectItemsEvents.ItemAdded
event just before calling
AddFromTemplate, and store away the
ProjectItem passed to your OnItemAdded
handler.
http://msdn.microsoft.com/en-us/library/envdte.projectitems.addfromtemplate(v=vs.80).aspx#1

Categories

Resources