This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C# wrap method via attributes
I'd like to achieve such functionality:
[Atomic]
public void Foo()
{
/* foo logic */
}
Where [Atomic] attribute is an attribute, which wraps function logic within a transaction scope:
using(var scope = new TransactionScope())
{
/* foo logic */
scope.Complete();
}
How to write such an attribute?
I've asked before basically the same question, I know this can be done using AOP, but I didn't mention I'm searching for some simplest proof of concept implementation or helpful articles which can help me to write this using pure .NET Framework (I suppose using RealProxy and MarshalByRefObject types, about which I've read browsing related questions).
I need to solve exactly this shown example. It seems like a basic thing so I want to learn how to do it starting from scratch. It doesn't need to be safe and flexible for now.
It seems like a basic thing...
It's one of the (many) things which are simple to understand the concept, but not at all simple to implement.
As per Oded's answer, Attributes in .NET don't do anything. They only exist so that other code (or developers) can look at them later on. Think of it as a fancy comment.
With that in mind, you can write your attribute like this
public class AtomicAttribute : Attribute { }
Now the hard part, you have to write some code to scan for that attribute, and change the behaviour of the code.
Given that C# is a compiled language, and given the rules of the .NET CLR there are theoretically 3 ways to do this
Hook into the C# compiler, and make it output different code when it sees that attribute.
This seems like it would be nice, but it is simply not possible
right now. Perhaps the
Roslyn
project might allow this in future, but for now, you can't do it.
Write something which will scan the .NET assembly after the C# compiler has converted it to MSIL, and change the MSIL.
This is basically what PostSharp does. Scanning and rewriting MSIL is hard. There are libraries such as Mono.Cecil which can help, but it's still a hugely difficult problem. It may also interfere with the debugger, etc.
Use the .NET Profiling API's to monitor the program while it is running, and every time you see a function call with that attribute, redirect it to some other wrapper function.
This is perhaps the simplest option (although it's still very difficult), but the drawback is that your program now must be run under the profiler. This may be fine on your development PC, but it will cause a huge problem if you try deploy it. Also, there is likely to be a large performance hit using this approach.
In my opinion, your best bet is to create a wrapper function which sets up the transaction, and then pass it a lambda which does the actual work. Like this:
public static class Ext
{
public static void Atomic(Action action)
{
using(var scope = new TransactionScope())
{
action();
scope.Commit();
}
}
}
.....
using static Ext; // as of VS2015
public void Foo()
{
Atomic(() => {
// foo logic
}
}
The fancy computer science term for this is Higher order programming
Attributes are meta data - that's all they are.
There are many tools that can take advantage of such metadata, but such tooling needs to be aware of the attribute.
AOP tools like PostSharp read such metadata in order to know what and where to weave aspects into code.
In short - just writing an AtomicAttribute will give you nothing - you will need to pass the compiled assembly through a tool that knows about this attribute and do "something" to it in order to achieve AOP.
It is not a basic thing at all. No extra code is run just because a method has an attribute, so there is nowhere to put your TransactionScope code.
What you would need to do is at application start-up use reflection to iterate over every method on every class in your assembly and find the methods that are marked with AtomicAttribute, then write a custom proxy around that object. Then somehow get everything else to call your proxy instead of the real implementation, perhaps using a dependency injection framework.
Most AOP frameworks do this at build time. PostSharp for example runs after VisualStudio builds your assembly. It scans your assembly and rewrites the IL code to include the proxies and AOP interceptors. This way the assembly is all set to go when it is run, but the IL has changed from what you originally wrote.
Maybe resolve all objects using IoC container?
You could configure interceptors for your types and in them check if called method is decorated with that attribute. You could cache that information so that you don't have to use reflection on every method call.
So when you do this:
var something = IoC.Resolve<ISomething>();
something is not object you have implemented but proxy. In that proxy you can do whatever you want before and after the method call.
Related
I want to log the entry of methods. In entry log I would have inputs\parameters received by the method. This has to be done for thousands of methods.
I thought of doing this logging of input parameters using C# ATTRIBUTES, since they fired before method call. (Something similar to ActionFilters in MVC)
Is that possible to read method parameters through attributes?
The concept you are looking for is called aspect oriented programming (AOP). It is a technique that allows you to "weave" in blocks of boilerplate code across your application code. Logging is a perfect example for that. You can either go the hard way and implement logging before and after each method call manually (which is on the one hand not feasible in large projects and on the other hand error prone).
Or you can use an AOP Framework that allows you to define these cross cutting functions in one place and apply it declaratively to your application code. There are several approaches to achieve this; one is to create IL after the build of the application logic and therefore integrating the aspects at compile time. A well known example for this is PostSharp. There also is a free edition that is good for the start.
BTW: PostSharp heavily relies on attributes, so you're on the right track.
Another option is to integrate the aspects at run time (keyword is interception). Most IoC Frameworks offer this. This approach is easy to use but has some downsides IMHO (weaker runtime Performance, only virtual methods can be intercepted).
Attributes are not 'fired before method call', the code that invokes a method that is decorated with an Attribute may (or may not) do something based on the presence of the Attribute.
The Attribute doesn't know the member it is applied on, nor can access it in any (straight forward) way.
For my own amusement and to learn the C# reflection APIs, I've been toying with the idea of an useless application built completely out of plugins, such that the only thing done by the main program is to read a config file, and load a plugin that will proceed to load every other assembly it's been configured to load on the fly.
To do this, I was thinking of using attributes to define (...)services(?) and events (for the sake of argument, let's call them ServiceAttribute(string) EventAttribute(string), where the parameter is the name of the hook), and then keep a table of where we can find these. An example would be like this
namespace example{
public class Plugin : IPlugin{
[Service("myService")]
public void PrintFrickingEverything(params string[] toPrint){
foreach(string s in toPrint){
Console.WriteLine(s);
}
}
}
}
And the hook would be accessed somehow by asking for "example.Plugin.myService"
However, a couple of things stick in my head,
one: this implementation seems to be Martin Fowler's service locator pattern, which I think it couples things too tightly together, and would rather avoid it if possible.
two: While I've done something similar to make a dispatcher for plugins in PHP, the type safety in C# makes this approach difficult.
I know I could use MS's library for this kind of thing, but I want to build this from the ground up by myself so I can learn about it along way to help me with other things I want to write later on.
Anyway, tl;dr: I want to get past the typing system somehow and be able to keep these methods somewhere, yet still be able to call them without needing to resort to casting an array of objects. Is it possible?
YES.
What you are trying to do is how we did plugins years ago, and it works okay. Nowadays we have MEF to do it, however to learn I recommed taking a look at this: http://www.codeproject.com/Articles/6334/Plug-ins-in-C
Here's a rather unpleasant pickle that we got into on a client site. The client has about 100 workstations, on which we deployed version 1.0.0 of our product "MyApp".
Now, one of the things the product does is it loads up an add-in (call it "MyPlugIn", which it first looks for on a central server to see if there's a newer version, and if it is then it copies that file locally, then it loads up the add-in using Assembly.Load and invokes a certain known interface. This has been working well for several months.
Then the client wanted to install v1.0.1 of our product on some machines (but not all). That came with a new and updated version of MyPlugIn.
But then came the problem. There's a shared DLL, which is referenced by both MyApp and MyPlugIn, called MyDLL, which has a method MyClass.MyMethod. Between v1.0.0 and v1.0.1, the signature of MyClass.MyMethod changed (a parameter was added). And now the new version of MyPlugIn causes the v1.0.0 client apps to crash:
Method not found: MyClass.MyMethod(System.String)
The client pointedly does not want to deploy v1.0.1 on all client stations, being that the fix that was included in v1.0.1 was necessary only for a few workstations, and there is no need to roll it out to all clients. Sadly, we are not (yet) using ClickOnce or other mass-deployment utilities, so rolling out v1.0.1 will be a painful and otherwise unnecessary exercise.
Is there some way of writing the code in MyPlugin so that it will work equally well, irrespective of whether it's dealing with MyDLL v1.0.0 or v1.0.1? Perhaps there's some way of probing for an expected interface using reflection to see if it exists, before actually calling it?
EDIT: I should also mention - we have some pretty tight QA procedures. Since v1.0.1 has been officially released by QA, we are not allowed to make any changes to MyApp or MyDLL. The only freedom of movement we have is to change MyPlugin, which is custom code written specifically for this customer.
The thing is that the changes you made have to be basically in addition and not the change. So if you want to be back compatible in your deployment (as much as I understood in current deployment strategy you have this is an only option) you should never change the interface but add a new methods to it and avoid tight linking of your plugin with shared DLL, but load it dynamically. In this case
you will add a new funcionality without disturbing a old one
you will be able to choose which version of dll to load at runtime.
I have extracted this code from an application I wrote some time ago and removed some parts.
Many things are assumed here:
Location of MyDll.dll is the current directory
The Namespace to get reflection info is "MyDll.MyClass"
The class has a constructor without parameters.
You don't expect a return value
using System.Reflection;
private void CallPluginMethod(string param)
{
// Is MyDLL.Dll in current directory ???
// Probably it's better to call Assembly.GetExecutingAssembly().Location but....
string libToCheck = Path.Combine(Environment.CurrentDirectory, "MyDLL.dll");
Assembly a = Assembly.LoadFile(libToCheck);
string typeAssembly = "MyDll.MyClass"; // Is this namespace correct ???
Type c = a.GetType(typeAssembly);
// Get all method infos for public non static methods
MethodInfo[] miList = c.GetMethods(BindingFlags.Public|BindingFlags.Instance|BindingFlags.DeclaredOnly);
// Search the one required (could be optimized with Linq?)
foreach(MethodInfo mi in miList)
{
if(mi.Name == "MyMethod")
{
// Create a MyClass object supposing it has an empty constructor
ConstructorInfo clsConstructor = c.GetConstructor(Type.EmptyTypes);
object myClass = clsConstructor.Invoke(new object[]{});
// check how many parameters are required
if(mi.GetParameters().Length == 1)
// call the new interface
mi.Invoke(myClass, new object[]{param});
else
// call the old interface or give out an exception
mi.Invoke(myClass, null);
break;
}
}
}
What we do here:
Load dynamically the library and extract the type of MyClass.
Using the type, ask to the reflection subsystem the list of MethodInfo present in that type.
Check every method name to find the required one.
When the method is found build an instance of the type.
Get the number of parameters expected by the method.
Depending on the number of parameters call the right version using Invoke.
My team has made the same mistake you have more than once. We have a similar plugin architecture and the best advice I can give you in the long run is to change this architecture as soon as possible. This is a maintainability nightmare. The backwards compatibility matrix grows non-linearly with each release. Strict code reviews can provide some relief, but the problem is you always need to know when methods were added or changed to call them in the appropriate way. Unless both the developer and reviewer know exactly when a method was last changed you run the risk of there being a runtime exception when the method is not found. You can NEVER call a new method in MyDLL in the plugin safely, because you may run on a older client that does not have the newest MyDLL version with the methods.
For the time being, you can do something like this in MyPlugin:
static class MyClassWrapper
{
internal static void MyMethodWrapper(string name)
{
try
{
MyMethodWrapperImpl(name);
}
catch (MissingMethodException)
{
// do whatever you need to to make it work without the method.
// this may go as far as re-implementing my method.
}
}
private static void MyMethodWrapperImpl(string name)
{
MyClass.MyMethod(name);
}
}
If MyMethod is not static you can make a similar non-static wrapper.
As for long term changes, one thing you can do on your end is to give your plugins interfaces to communicate through. You cannot change the interfaces after release, but you can define new interfaces that the later versions of the plugin will use. Also, you cannot call static methods in MyDLL from MyPlugIn. If you can change things at the server level (I realize this may be outside your control), another option is to provide some sort of versioning support so that a new plugin can declare it doesn't work with an old client. Then the old client will only download the old version from the server, while newer clients download the new version.
Actually, it sounds like a bad idea to change the contract between releases. Being in an object-oriented environment, you should rather create a new contract, possibly inheriting from the old one.
public interface MyServiceV1 { }
public interface MyServiceV2 { }
Internally you make your engine to use the new interface and you provide an adapter to translate old objects to the new interface.
public class V1ToV2Adapter : MyServiceV2 {
public V1ToV2Adapter( MyServiceV1 ) { ... }
}
Upon loading an assembly, you scan it and:
when you find a class implementing the new interface, you use it directly
when you find a class implementing the old interface, you use the adapter over it
Using hacks (like testing the interface) will sooner or later bite you or anyone else using the contract - details of the hack have to be known to anyone relying on the interface which sounds terrible from the object-oriented perspective.
In MyDLL 1.0.1, deprecate the old MyClass.MyMethod(System.String)and overload it with the new version.
Could you overload MyMethod to accept MyMethod(string) ( version 1.0.0 compatible) and MyMethod(string, string) (v1.0.1 version)?
Given the circumstances, I think the only thing you can do really is have two versions of MyDLL running 'side by side',
and that means something like what Tigran suggested, loading the MyDLL dynamically - e.g. as an a side example not related but might help you, take a look at the the RedemptionLoader http://www.dimastr.com/redemption/security.htm#redemptionloader (that's for an Outlook plugins which often have problems crashing to each other referencing different versions of a helper dll, just as a background story - that's a bit more complex cause of the COM involved but doesn't change much here) -
it's what you can do, something similar. Load dynamically the dll by it's location, name - you can specify that location internally, hard-code, or even set it up from config or something (or check and do that if you see that MyDll is not of the right version),
and then 'wrap' the objects, calls form the dynamically loaded dll to match what you normally have - or do some trick like that (you'd have to wrap something or 'fork' on the implementation) to make everything work in both cases.
Also to add on the 'no-nos' and your QA sorrows :),
they should not break the backward compatibility from 1.0.0 to 1.0.1 - those are (usually) the minor changes, fixes - not breaking changes, major version # is needed for that.
In C++ I would get the address of the function and overwrite the first few bytes to a jmp to my function, do some stuff, restore the original bytes, and call the original function.
Can I do something like this in C#?
The .NET Profiler API is the closest "Microsoft-approved" way of intercepting methods at runtime. As already mentioned, this is somewhat difficult to implement and I am not aware of a library that makes this easy to implement using purely managed code.
While researching options for this myself a few months ago, I stumbled on CLR Method Injection, which is an article with source code explaining how to intercept methods at runtime. I considered using this myself, and even had the sample project working, but ultimately concluded that I needed more than method interception and would need a different solution. However, this approach directly answers your question.
Lastly, what I ended up doing was developing Afterthought as an open source alternative to PostSharp, which runs as a post-compile step and allows you to modify existing methods to call other code, or replace the method implementations altogether. I am working right now on a new fluid syntax, which I will include a sample of now to provide an example to help you see how this AOP approach would meet your needs:
Methods
.Named("Sum")
.WithParams<int[]>()
.Before((T instance, ref int[] values)
=> { var s = new Stopwatch(); s.Start(); return s; })
.After((instance, stopwatch, values)
=> instance.Result = (int)stopwatch.ElapsedMilliseconds);
In this case while amending an existing type with a Sum method I am introducing code before and after the method to measure the execution time. After running Afterthought against the original compiled class, the resulting Sum method would have calls to these lambda expressions (the C# compiler just turns them into static methods) before and after the method body. I could have just as easily called Implement and replaced the entire method implementation.
I hope one of these approaches meets your needs. In my case, I went the AOP route because I wanted to do more than interception, such as implementing interfaces, adding new methods/properties, etc. I also wanted something that would not introduce dependencies at runtime or concerns about stability or performance in the runtime environment--compile-time processing is just safer and easier to test.
Do you want to hook at runtime or do you want to patch the binary?
To hook at runtime you can use the profiling api(relatively difficult):
http://msdn.microsoft.com/en-us/magazine/cc188743.aspx
To hook at compiletime you can use an IL rewriter, such as PostSharp.
The technique you're looking for is called AOP - Aspect Oriented Programming. You can find several frameworks for C# if you goggle a little.
Update: You can find plenty of links and info in this question: Built-in AOP in C# - is it on the way?
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.