I'm trying to get insights about how transparent proxy created by WCF ChannelFactory work by digging into source codes. CreateTransparentProxy is marked by extern keyword and [MethodImplAttribute(MethodImplOptions.InternalCall)] attribute which means that I must look implementation inside CLR as long as my understanding goes. In CLR source codes I found only one mention of function that I need in some sort of c# to c++ code functions mapping file ecalllist.h. So implementation must be lying within class called RemotingNative, but search within repository doesn't give me any result on that.
I've found some old SSCLI codes on github which contains similar method implementation but not exactly the same. And besides that I want to look at actual implementation.
WCF become open sourced the other day. What I found so far is that WCF ServiceChannelProxy now use DispatchProxy.Create<T, TProxy>() instead of RemotingServices.CreateTransparentProxy(). So it looks like if you want actual implementation of method that creates proxy used by WCF, than DispatchProxy and DispatchProxyGenerator are places that you look for. If you want actual implementation of RemotingServices.CreateTransparentProxy() than SSCLI codes may be a good approximation as #Christian.K pointed out.
Related
we are using a 3rd party library (ORM Mapper) to access a database. This library has no support anymore.
Short time ago we found some bug in a specific method in this library (it crashes when it gets not-unique entities in a list to save in the database) and I implemented a C# extension class where this bug is fixed, an I also found and replaced all calls for a library method with my extension and communicated this issue with my team.
Now I want to prevent using of library method in our code base, so it's only an extension class call permitted. How can I ensure nobody can use a library method in the future or at least he will be notified that this call is prohibited.
I took a look on ReSharper's External Annotations, but did not found it useful in my case.
I ended up writing a small custom code analyzer based on "Analyzer with Code Fix" Microsoft's template and then added resulting dll in our project, so me and my teammates can use it. This article helped me a lot.
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.
i'm adding comments to some csharp code, and i'm using the xml language provided by .net (or something). i have an interface, and some implementing classes. i have one method in the interface, and it has a comment. in the implementing classes there is no comment on the implementing method.
when one does it like this in java, javadoc automagically uses the interface comment when generating documentation. however, now that i build my project, i get the warning (transalted from swedish, sorry) "the xml comment for the visible type or member bla.blabla.blablabla() is missing (cs1591)". this is only a warning, so not so bad. but!!! it means no xml file was output, so i can't use sandcastle to generate a chm document file, which is my real goal here.... googling the error coded gave nothing :(
do i really have to copy the method comment to all implementing classes? that's like.... code duplication D: is there no way to get the behavior java offers?
I don't know of any way of getting it to happen at XML file generation time, but GhostDoc may well save you from performing the copying manually. I can't say I've used it myself though.
I agree that it would be a valuable feature... particularly if the base class (or interface) documentation changes after the derived classes have been implemented and documented.
You do have to copy the interfaces comments to the implementing class. Generally this is a good thing as the two comments should ideally be different - my opinion (and practise) on this can be summarised as the following:
Interface Comments - Explains what the method/property/etc is supposed/expected to do but should generally not proscribe how any specific implementation should behave
Implementing Class Comments - Explains what the method/property/etc actually does and may include some details of how this is done (typically in <remarks>)
VSdocman can resolve missing XML comments from implemented interfaces automatically when it generates documentation. Moreover, like GhostDoc, it can also explicitly copy inherited comments to the implementing method. Unlike Sandcastle, it's not free.
Well i dont know about Java but Sorry you will have to copy the interface's comments in the implemented class. here is no inbuilt way of doing it...
And yeah consider the suggestion given by JonSkeet
I've got main project, and a series of dll's that have specific implementations of some interfaces as well as view\viewmodels, etc. I use {ImportMany] to get them all with some metadata, which allows me to choose one, which gives me a reference to the specific implementation of ISystem.
I'd like to get the only specific implementation of IDisplay from whatever dll the ISystem is chosen from, which I marked with [Export("SomeDisplay", typeof(IDisplay))]
So far, the only thing that I can find that looks like it might work is GetExports(ImportDefinition), but I don't understand how to create an ImportDefinition that would work, as it seems to want a specific contractname, which isn't known until runtime.
Of course since I'm still a MEF n00b, it's a good bet I'm doing it wrong :D
So, if GetExports is the best way, how can I make it work? Or is there a better way I should be using?
Thanks!
You need to look into providing metadata along with your MEF exports.
See these articles and blog posts for details:
Building Hello MEF – Part II – Metadata and why being Lazy is a good thing.
MEF for beginner - Part 8 - Metadata
Providing metadata to your MEF exports
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.