How do I get an instance of IVsExpansionClient in VSPackage? - c#

Documentation for extending Visual Studio is virtually nonexistent, and I managed to assemble a few lines of functioning code hacked together from a dozen or more obscure sources around the interwebs before crashing into a brick wall.
All I need to do is subscribe to an event that is fired after a snippet is inserted. Sounds easy enough, or so I thought. Almost immediately into my research I stumbled upon the following morsel:
IVsExpansionClient.OnAfterInsertion
That describes perfectly my intention, so this MUST be the answer! After looking around my SDK assemblies for longer than I would like to admit, I finally ended up yanking the assembly (Microsoft.VisualStudio.TextManager.Interop.8.0.dll) out of my GAC so that I could reference it explicitly in my solution.
Now that I have access to the interface, I just need to figure out how to get an instance of it.
IVsExpansionManager
Ah HA! That MUST somehow provide me with a mechanism for obtaining an instance of IVsExpansionClient, right? Well, not exactly. At least not in a way that I can see. I have stitched together the following code:
IVsExpansionManager expansionManager = null; IVsTextManager2
textManager =
(IVsTextManager2)Package.GetGlobalService(typeof(SVsTextManager)); int
manager = textManager.GetExpansionManager(out expansionManager);
Which gives me a IVsExpansionManager COM object, but that is about as far as I can get.
I have taken notice of another potential provider:
IVsExpansionEvents
I thought perhaps like solution events, document events, window events or text events, I might be able to invoke DTE to hook these events, but they appear to be absent.
There are methods that accept IVsExpansionClient as a parameter such as:
IVsExpansion.InsertNamedExpansion
So there simply must be a way to fetch an instance of this object, right? I suppose it's possible to create my own class that implements the IVsExpansionClient interface, but I wouldn't know where to begin with implementing the interface members, and I still wouldn't know how to instantiate it in a meaningful way within my package.
I am grateful to anyone who can point me in a different direction, or provide a working sample that I can adapt for my needs. Thanks for taking the time to read through this, I appreciate your time.
EDIT: I want to receive a notification that a snippet has been inserted into the active document window. Ideally, I would like the snippet itself to be included in the delegate event args, as I have some processing to do on the inserted snippet...and it would be cumbersome to process the entire document, or try to identify the recently inserted snippet without context.

Maybe you want to explain what you actually want to achieve. The documentation of the IVsExpansionClient interface states:
Notes to implementers
This interface is implemented by a VSPackage that supports insertion of code snippets.
I don´t see why one would like to consume an instance of it, because it´s an interface allowing the package to receive notifications/callbacks, if something related to code-snippets is going to happen (it provides nohting else than callback functions).
It states furthermore...
Notes to Callers
This interface is instantiated and passed to the InvokeInsertionUI method in the IVsExpansionManager interface. This interface is also instantiated and passed to the methods in the IVsExpansion interface.

Related

Mark method as obsolete for a single project

Due to the way our codebase works, I was advised to not edit certain methods in a shared codebase. Instead, I decided to make a new method that calls the old one and also does the new work our team wanted that method to do. The issue I am foreseeing is not everyone on the team being aware of the new method and still using the old one from the shared codebase.
TLDR:
Shared codebase has SharedCode.Function.
I created OurCode.Function which does some stuff, and then calls SharedCode.Function.
I cannot edit SharedCode.Function or it's containing project.
Is it possible to mark SharedCode.Function as obsolete within our project as a compiler warning somehow or otherwise mark that OurCode.Function essentially replaces it?
EDIT:
Might be pertinent to mention- these are logging functions, so if a dev accidentally calls SharedCode.Function instead of OurCode.Function, the only result is that we capture less data than we desired, it will still compile and run fine. This is a major reason I want to try to make it a compiler warning, so that any dev that doesn't know to use the new function will find out to.
The shortest way is by adding the ObsoleteAttribute as an attribute
to the method. Make sure to include an appropriate explanation:
[Obsolete("Method1 is deprecated, please use Method2 instead.")]
public void Method1()
{ … }
I think the adapter pattern could work wonders in this particular scenario. Essentially you end up creating an abstraction between OurCode and SharedCode.
This isolates access to SharedCode functions so that only the adapter can use the shared code's functions. It may end up that some of the functions in the adapter simply provide a pass through, but some of those functions will have extra logic that needs to be applied (such as in the scenario you are asking about), and having the adapter makes it easy for you to enforce that.
All client code is forced to use the adapter since they cannot directly access the shared code.
If you had access to the source code, I would recommend using the Obsolete attribute that the others have pointed out. But since you don't have access to the code base, I think it could be extremely beneficial to have a layer of abstraction between your code and the non-accessible code.
Now obviously I do not have the full scope of your scenario as to whether or not this makes sense to actually implement, so don't drive blindly, but hopefully this gives you some ideas! :)
Reference the gang of four book or see the following resources:
https://martinfowler.com/bliki/RequiredInterface.html
https://www.dofactory.com/net/adapter-design-pattern
Understanding Adapter Pattern

How to Instantiate object of private class from .DLL? [duplicate]

This question already has answers here:
Instantiating Internal class with private constructor
(5 answers)
Closed 7 years ago.
I'm either googling the wrong thing or trying to head down the completely wrong path (most likely)... but now I'm curious so I thought I'd ask.
Long story short, I'm trying to tap into the underlying "API" framework of Microsoft's Message Analyzer tool for a custom application. I say "API" because there is no formal support for an API, no documentation, and there won't be any in the near future, if ever (so says Paul at Microsoft anyway). So instead I've been using the IL DASM tool to poke around some of the Message Analyzer and PowerShell .dlls to try to get an understanding of how this stuff works; the ultimate goal of course is to use MA's .dlls and drivers to do what I want for the custom app. I'm looking at Microsoft.Protocols.Tools.PowerShell.dll, which has a class (Microsoft.Protocols.Tools.PowerShell.PpkTraceSession) that I'm trying to instantiate:
However, if you look right below it, it says something about the class being private (it's cut off in the picture, but the class does implement IPpkTraceSession and IPpkTraceSessionEx). Sure enough, when I reference this .dll in some C# code and try to instantiate an object, I get a compile error saying its inaccessible due to its protection level:
Windows PowerShell has no problem at all creating one of these objects. It just so happens the printout seen below matches all the properties (not seen in the first picture) of the PpkTraceSession class, so I know Windows PowerShell is working some magic to create an object of that class,, I just can't figure out how since apparently this class is private.
So my question,, what's going on here? I've poked around in a lot of the classes shown in the IL DASM output, and there are a surprising number of them that appear to be private. Maybe it's just my bad practice, but I've rarely if ever used or seen many private classes. It's my understanding they have to be nested in other classes to be of any particular use. If PpkTraceSession is nested in another class, that's not clear from the IL DASM output at all. You may see the IPpkTraceSession(Ex) interfaces above,, if there's a way to access the class properties using those I haven't figured it out yet. Is there anyway to instantiate an object of this class, or am I going about this all wrong?
This might be close to a duplicate, but not quite I don't think. Any help is much appreciated! I clearly don't know much about Windows programming.
yano
EDIT:::::
Just to tie off all the loose ends (in case somebody else makes my mistake), I discovered the source of my confusion a couple of days ago. All the classes indicated as "private" by the IL DASM tool are actually "internal" classes, meaning that they're meant to be visible only within their own assembly. That was my missing piece, I couldn't understand where all these private classes were coming from when C# won't even let you compile a standalone private class (it must be nested within another class). I should've done some more research on IL DASM before I posted a question, but it didn't even occur to me; I thought private meant private. It's my observation that IL DASM does make a distinction between private/internal classes and nested private classes. This issue has also already been addressed here: When I declare a class as internal, why does the IL show it as private? . Thanks for the help everyone!
I suspect that what you are seeing is that other classes, probably deep inside the PowerShell plumbing, might expose some of the properties of the PpkTraceSession class. You might be able to find them by inspecting the intermediate language of the public classes exposed by the same dll THAT contains the private PpkTraceSession class. However, I suspect that you are wasting your time, and will not find a way to use those classes in your own code.
They are marked private because Microsoft has no intention of supporting them, and their behavior might change without notice. That isn't a problem within the PowerShell team, which has access to them, most likely through other private classes. So, if they need to change the way one of those classes behaves, they can do it, and the affected audience is small and easily reachable.
Speaking as a developer, I can think of a host of reasons that Microsoft might not want to support it, such as that it is very fussy, or that doing so would involve disclosing proprietary or patented technology that they have a legal right to keep secret.
Perhaps you could start a campaign to make them public, but you'll need to make a really good case, and convince a lot of other people, preferably people who already pay Microsoft a lot of money, to get behind you.

pass data from one activity to another in Xamarin.Android

I wanted to pass a Class Object from one activity to another in Xamarin.Android app.
I can pass the simple strings using Intent.PutExtra method.
Does anybody know about it. anyhelp is appreciated :)
Just adding in case someone else comes across this. The nice thing about Xamarin/.NET is how easy it is to use JSON. You can Serialize your data to a string and pass that through the Extras.
JSON.NET is a nice library (that you can find on the Xamarin component store) for this and there is also some built in JSON classes in .NET. An example using JSON.NET would be like this.
Intent i = new Intent(Application.Context, typeof(SecondActivity));
i.PutExtra("key", JsonConvert.SerializeObject(myObject));
StartActivity(i);
And in the other Activity you can deserialize it.
var obj = JsonConvert.DeserializeObject<OBJ_TYPE>(Intent.GetStringExtra("key"));
This is better than using a static reference in my opinion.
The concept is the same as with a standard (non-Xamarin) application.
You can use Intent#putExtra(String, Parcelable) to pass any object that implements the Parcelable interface as an extra.
The Parcelable interface is a little bit complex, so be sure to read the documentation to ensure that your class conforms to the requirements. You may also want to check out this SO question for more information on creating a Parcelable class.
You cannot pass an object reference via an Intent. This is because Activities are designed to work completely independently of each other. Users can throw your Activity in the background while performing other tasks, so it is entirely possible (and very likely) that your Activity's variables will be garbage collected. When the user later comes back to your Activity, it should be able to recreate its state.
If you really need to pass a reference to an object directly, you can do so by making that object a static variable. While this is a quick and dirty way to solve the problem of getting data from one Activity to another, it does not solve the problem of the variable potentially being garbage collected at some point, and is generally a poor design choice.

Why does MSDN recommend including object sender in delegate declarations?

I was reading this page and I noticed how it said this is standard guidelines:
The .NET Framework guidelines indicate that the delegate type used for an event should take two parameters, an "object source" parameter indicating the source of the event, and an "e" parameter that encapsulates any additional information about the event.
I can understand how having an object sender could be useful in some circumstances, but I could see the exact opposite in others. For example,
What if a class handling the event should not have any knowledge about who fired it? Coupling, cohesion, and all of that.
In my case, I already have a reference to the object as a member variable. That is how I subscribe to the event. There will only ever be one instance of it so there's no reason to cast the sender object rather than just using the member variable.
In my program the sender object should not be known at all to the clients. It's hard to explain what I am doing but basically I have a class with an internal constructor within a library that is used by two other classes also within that library. My client classes are subscribing to events from those two classes but the events are originally invoked from this internal class that clients should not have any knowledge of.
It is confusing to clients of the event handler. Libraries should be simple to understand and in my case, there is no reason to ever use the sender variable. None. Then why include it?
That being said, why does Microsoft indicate that event handlers should follow these guidelines? Isn't it not always the best choice?
EDIT: Thanks for the replies everyone. I've decided to go with the majority and use EventHandler<T> for all my events in this library.
You are fighting against the wind, the .NET framework has certain design, rules and guidelines and when using it, if you want to use it correctly, you are supposed to follow those directions.
if you use raw delegates you have all the freedom you want but as stated above if you are declaring a delegate type for an event you should include sender object and EventArgs object as well (base or derived class).
if you break those rules, as I said a moment ago in my answer to your other question: Should I use EventArgs or a simple data type?, you could potentially end up in a situation where your code breaks.
Simplyfying at the maximum, when the framework invokes an OnClick event on a control, the .NET Framework does pass the sender and an EventArgs instance... if the event would not comply, something could break.
if you want full freedom then use simple delegates but not events.
First of all, it's important to note that a guideline is not a law.
All hell (or the programmer equivalent) will not break lose if you don't follow the guidelines.
As such, feel free to change the signature of your events appropriately.
However, it is just as important to know why these guidelines were added to begin with, and one big part of the answer(s) to that question is versioning.
By having the following two parts, and only those two parts:
The source of the event, typed as "generic" as possible (note, event signatures were designed long before proper generics were introduced into the system, so object is as generic as can be from back then)
An object inheriting from EventArgs
then you are designing code that is more resilient to changes.
First of all, since you're not "allowed" to add or remove parameters, all future versions of your event will still have only sender and e.
Secondly, there's a second part to the guideline regarding the e parameter. If you in a new version of your class library decides to change the signature of an event handler by changing the type of the e parameter, you're supposed to make it more specific by descending from your current type, and passing the descendant instead.
The reason for this is that existing code that already handles your current (old) type will still work.
So the entire reasoning behind the guideline is to:
Stay consistent (as others have mentioned)
Design for the future (by making sure code written against version X of your class still works when you release version X+1, without manual changes to that code)
Now, if any of this is not a concern for your case, feel free to not follow the guideline.
In fact, you can make an event out of an Action and it'll work just fine.
Why? People always ask this. In this end, this is just about a
pattern. By having event arguments packaged in a class you get better
versioning semantics. By having a common pattern (sender, e) it is
easily learned as the signature for all events. I think back to how
bad it was with Win32—when data was in WPARAM versus LPARAM, and
so on. The pattern becomes noise and developers just assume that event
handlers have scope to the sender and arguments of the event.
-Chris Anderson, in Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries
If you're a .NET developer and you haven't read that book, you're missing out. It gives you a window ;) into the minds of the Microsoft .NET Framework designers, and a lot of best practices (including the reasoning behind them).
(Plus, you can run FxCop to verify that these practices are being followed.)
I think the reason for the pattern is to enforce some consistency. The sender parameter allows re-use of a single handler for multiple publishers (buttons, tables).
To address your points:
1) simply don't use it. That is common and doesn't really hurt any good practice.
2) that's OK, again ignore the sender
3) is in total contradiction of what you said under 2) ...
And for the rest it is the same as 1). You could even consider passing null as sender.
4) "then why include it" - there are other use cases that do require the sender.
But do note this is just a guideline for libraries confirming to the BCL.
Your case sounds more like a specific application (not a library) so feel free to use any parameter scheme you like. The compiler won't complain.
Guidelines such as this allow for predictability on the part of the consumer of the event. It also allows for handling of additional scenarios you may never have considered when you created the event, especially if your library is used by third party developers.
It allows the method handling the event to always have the correct object instance at hand as well as basic information regarding why the event was fired.
It's just good practice, but you'll be fine as long as you don't need to know about the object that fired the event or any other info related to the object. I for one always include it since you never know when you'll need it.
My suggestion is to stick with it, it does not hurt at all.
There would have been nothing wrong, semantically, with having event handlers that are interested in where events came from use a derivative of EventArgs which included such a field. Indeed, there are many situations where that would be cleaner than passing Sender as a separate parameter (e.g. if a keyboard-shortcut processor needs to fire a Click handler for a button, the event shouldn't really be considered to have been raised by the button, but rather raised on the button's behalf). Unfortunately, incorporating that information within an EventArgs-derived type would make it necessary to create a new instance of an EventArgs-derived type every time an event is raised, even if it could otherwise use EventArgs.Empty. Using a separate parameter to pass the information eliminates the need to have every event create a new object instance in that common case.
Although it might have been possible to have handlers that care about where an event came from use a parameter for that, and have those that don't care about it omit the parameter, that would have required that any helper methods and classes which assist with handling event subscriptions would need to have versions for events which did or did not include the parameter. Having all events take two parameters, one of which is of type Object and one of which is of a type derived from EventArgs makes it possible for one helper method or class to be capable of handling all events.

Is there an equivalent to Java's ClassFileTransformer in .NET? (a way to replace a class)

I've been searching for this for quite a while with no luck so far. Is there an equivalent to Java's ClassFileTransformer in .NET? Basically, I want to create a class CustomClassFileTransformer (which in Java would implement the interface ClassFileTransformer) that gets called whenever a class is loaded, and is allowed to tweak it and replace it with the tweaked version.
I know there are frameworks that do similar things, but I was looking for something more straightforward, like implementing my own ClassFileTransformer. Is it possible?
EDIT #1. More details about why I need this:
Basically, I have a C# application and I need to monitor the instructions it wants to run in order to detect read or write operations to fields (operations Ldfld and Stfld) and insert some instructions before the read/write takes place.
I know how to do this (except for the part where I need to be invoked to replace the class): for every method whose code I want to monitor, I must:
Get the method's MethodBody using MethodBase.GetMethodBody()
Transform it to byte array with MethodBody.GetILAsByteArray(). The byte[] it returns contains the bytecode.
Analyse the bytecode as explained here, possibly inserting new instructions or deleting/modifying existing ones by changing the contents of the array.
Create a new method and use the new bytecode to create its body, with MethodBuilder.CreateMethodBody(byte[] il, int count), where il is the array with the bytecode.
I put all these tweaked methods in a new class and use the new class to replace the one that was originally going to be loaded.
An alternative to replacing classes would be somehow getting notified whenever a method is invoked. Then I'd replace the call to that method with a call to my own tweaked method, which I would tweak only the first time is invoked and then I'd put it in a dictionary for future uses, to reduce overhead (for future calls I'll just look up the method and invoke it; I won't need to analyse the bytecode again). I'm currently investigating ways to do this and LinFu looks pretty interesting, but if there was something like a ClassFileTransformer it would be much simpler: I just rewrite the class, replace it, and let the code run without monitoring anything.
An additional note: the classes may be sealed. I want to be able to replace any kind of class, I cannot impose restrictions on their attributes.
EDIT #2. Why I need to do this at runtime.
I need to monitor everything that is going on so that I can detect every access to data. This applies to the code of library classes as well. However, I cannot know in advance which classes are going to be used, and even if I knew every possible class that may get loaded it would be a huge performance hit to tweak all of them instead of waiting to see whether they actually get invoked or not.
POSSIBLE (BUT PRETTY HARDCORE) SOLUTION. In case anyone is interested (and I see the question has been faved, so I guess someone is), this is what I'm looking at right now. Basically I'd have to implement the profiling API and I'll register for the events that I'm interested in, in my case whenever a JIT compilation starts. An extract of the blogpost:
In your ICorProfilerCallback2::ModuleLoadFinished callback, you call ICorProfilerInfo2::GetModuleMetadata to get a pointer to a metadata interface on that module.
QI for the metadata interface you want. Search MSDN for "IMetaDataImport", and grope through the table of contents to find topics on the metadata interfaces.
Once you're in metadata-land, you have access to all the types in the module, including their fields and function prototypes. You may need to parse metadata signatures and this signature parser may be of use to you.
In your ICorProfilerCallback2::JITCompilationStarted callback, you may use ICorProfilerInfo2::GetILFunctionBody to inspect the original IL, and ICorProfilerInfo2::GetILFunctionBodyAllocator and then ICorProfilerInfo2::SetILFunctionBody to replace that IL with your own.
The great news: I get notified when a JIT compilation starts and I can replace the bytecode right there, without having to worry about replacing the class, etc. The not-so-great news: you cannot invoke managed code from the API's callback methods, which makes sense but means I'm on my own parsing the IL code, etc, as opposed to be able to use Cecil, which would've been a breeze.
I don't think there's a simpler way to do this without using AOP frameworks (such as PostSharp). If anyone has any other idea please let me know. I'm not marking the question as answered yet.
I don't know of a direct equivalent in .NET for this.
However, there are some ways to implement similar functionality, such as using Reflection.Emit to generate assemblies and types on demand, uing RealProxy to create proxy objects for interfaces and MarshalByRefObject objects. However, to advise what to use, it would be important to know more about the actual use case.
After quite some research I'm answering my own question: there isn't an equivalent to the ClassFileTransformer in .NET, or any straightforward way to replace classes.
It's possible to gain control over the class-loading process by hosting the CLR, but this is pretty low-level, you have to be careful with it, and it's not possible in every scenario. For example if you're running on a server you may not have the rights to host the CLR. Also if you're running an ASP.NET application you cannot do this because ASP.NET already provides a CLR host.
It's a pity .NET doesn't support this; it would be so easy for them to do this, they just have to notify you before a class is loaded and give you the chance to modify the class before passing it on the CLR to load it.

Categories

Resources