Intercept Method Invocation or Property Change with Reflection - c#

I'm trying to create a generic class that will fire an event whenever a method is called or a property is accessed or changed. It may also fire events in response to other changes or actions being taken, but for now, that'll be it.
In order to do so, I'd like to intercept every method call and every property access/change, but I have no way of knowing exactly which methods I'm handling. There's no given interface that defines every generic type T I'll be working with, so I have to use reflection. Here's how I envision it (Trigger<T> is the class, and generic would be of type T):
public Trigger()
{
this.generic = default(T);
foreach (MethodInfo m in generic.GetType().GetMethods())
{
// This is pseudocode, since I can't just set MethodInfo to a new method
m = delegate()
{
m.Invoke(this.generic, null);
if (MethodCalled != null)
MethodCalled(this, eventArgs /*imagine these are valid EventArgs*/);
};
}
}
I realize that I've grossly oversimplified the problem. First off, I'd have to deal with parameters. Second, you can't just override a method programmatically like that. And third, I haven't even started on properties yet. Plus, I'd have to be changing these things for only the object, not the entire type, so I'm not sure how that works either.
I've done my research, and all I find is confusing content. I realize that I'm somehow supposed to be using AOP, but I've never done anything other than OOP and procedural programming, so I'm rather lost in this dense jungle of knowledge. It sounds like I'll need to use PostSharp or Unity, but I still have no clue how after looking at all this, and this, and these two, and also this (all separate links, per word).
Is there any simpler way to do this? And can I even do it without using interfaces or predefined classes?
It's generics that make my problem particularly complicated. If I could just have a class inherit from T, and then use a proxy to capture its method calls and property accesses/changes, then things would maybe be a tad simpler, though I still lack the fundamental understanding of AOP to do that. Any help you can provide would be much appreciated. If possible, please write your answer at a beginner level (though I know my OOP fairly strongly, like I said, I don't know the first thing about AOP).

Without resorting to a full-on AOP framework that uses post-bulid IL weaving, you can use Castle's DynamicProxy and create an interceptor. You can find plenty of tutorials online:
Simple AOP
Short tutorial on CodeProject
This extensive one.
For your interceptor to work, you will need to make sure your generic class's methods and properties are virtual. This allows the DynamicProxy's runtime weaving code to generate a proxy that wraps your class.

You can do it like that using NConcern, a new open source AOP Framework on which I actively work.
public class Trigger<T> : Aspect
{
static public event EventArgs MethodCalled;
static private Trigger<T> m_Singleton = new Trigger<T>();
//Auto weaving aspect
static Trigger()
{
Aspect.Weave<Trigger<T>>(method => method.ReflectedType == typeof(T));
}
public IEnumerable<IAdvice> Advise(MethodInfo method)
{
//define an advice to trigger only when method execution not failed
yield return Advice.Basic.After.Returning(() =>
{
if (MethodCalled != null)
{
MethodCalled(this, null);
}
});
}
}
public class A
{
public void Test()
{
}
}
int main(string[] args)
{
Trigger<A>.MethodCalled += ...
new A().Test();
}
You can find a similar Example code source here : Example of observation pattern implemented with NConcern
NConcern AOP Framework is a light framework working at runtime. It work with code injection avoiding factory/proxy by inheritance. It allow you to add aspect to a class by injecting code you can create using simple delegate, ILGenerator or expression tree (linq) before/after or around a method. It can handle sealed class, sealed method, virtual method or explicit/implicit interface implementation.
Into my example, I create a class derived from Aspect (abstract class).
When a class derived from Aspect, it have to implement Advise method by returning an instance of Advice (Before/After/After.Returning/After.Throwing or Around). Each can be created with Delegate or Expression to define what you need to do on method interception.
public class MyAspect : IAspect
{
//this method is called initially (not on interception) to rewrite method body.
public IEnumerable<IAdvice> Advise(MethodInfo method)
{
//this block of code means that method will be rewrite to execute a write method name to console before original code only for public methods
if (method.IsPublic)
{
yield return Advice.Basic.Before(() => Console.WriteLine(method.Name));
}
}
}
Usage
//attach myaspect to A class. All methods of A will be passed to Advise method to process methods rewriting.
Aspect.Weave<MyAspect>(method => method.ReflectedType == typeof(A));
//detach myaspect from A class. All methods will be rewrite to give back original code.
Aspect.Release<MyAspect>(method => method.ReflectedType == typeof(A));

Related

Composition of objects vs functions: Should I use one method interfaces or delegates?

C# is a multi paradigm language. By nesting interfaces and classes one can get a composition of objects. This way a certain problem can be broken down to a number of simple ones giving each component its own piece of the puzzle to solve. The same trick can be done in a slightly different manner, one can make a composition of functions each of which is responsible of solving its own little task while all combined and interconnected they give the answer to the main problem.
Following SOLID principles I found myself in a situation where 95% of my interfaces carry just one method named do-something and the name of the interface is something-doer. The class that implements such interfaces is DI'ed with the a few components required to fulfill whatever that method is supposed to do. Such approach is basically making a closure over a function by hands. If so, why wouldn't I just go with delegates that do it naturally and for free (no typing necessary)? If I go all the way converting single method interfaces to delegates I will eliminate 95% of them from my code making it look like written in functional language. But this seems like a right thing to do unless there is some bold reason to stick with interfaces. Is there?
UPDATE:
#Fendy, Let me argue a bit. You have said
"You cannot control the delegate logic from BLL". Well, delegates can be defined anywhere not necessarily in callers. One can perfectly do this:
public namespace Bbl
{
public static class TestableUtils {
public static Func<A, B> CreateA2B() {
Func<A, B> a2b = a => new B(a);
return a2b;
}
public static Func<B, C> CreateB2C() {
Func<B, C> b2c = b => new C(b);
return b2c;
}
public static Func<A, C> CreateA2C(Func<A, B> a2b, Func<B, C> b2c)
{
Func<A, C> a2c = a => b2c(a2b(a));
return a2c;
}
}
}
public namespace Caller
{
using Bbl;
public class Demo()
{
public void RunMe()
{
var a = new A();
var a2b = TestableUtils.CreateA2B();
var b2c = TestableUtils.CreateB2C();
var a2c = TestableUtils.CreateA2C(a2b, b2c);
var c = a2c(a);
}
}
}
"If not careful, code duplication everywhere", That's true, be lazy and careful, so you don't do the same work more than once. The same problem can easily happen with classes. So delegates are no different.
"If constructor injected and using mutable entity, it can lead to stateful interface" I am sorry I don't see a problem with your example. I mean it does exactly what it programmed for. If you mutate entities this is what you would expect, wouldn't you? You can be safe just by preventing Name from being set outside of the constructor. If you do that then the situation from your example won't be possible.
Basically out of 4 points that you have laid out none has anything to do with having more problems using delegates compared to doing the same with interfaces/classes. Or I just didn't get it.
A delegate is, pretty much, a one method interface.
A closure is creating a new nested class, behind the scenes, it's just doing a lot of the related boilerplate for you to make the code cleaner.
In short, delegates and lambdas/closures were created to solve the problem that interfaces and nested classes are used for in languages without those features. You are not abusing these features to use them in this context.
That said, there isn't anything wrong with using classes/interfaces if you prefer it; it's just a bit more explicit. It's also more powerful, and is generally useful if the operation you're representing is more complex then a small class with a single method, so it's not like delegates and lambdas replaces interfaces entirely.
The answer is, as in the most application design applies, is "it depends".
As you already know, delegates are defined in the caller. It means that:
You cannot control the delegate logic from BLL. This is also means NO UNIT TEST for the function
If not careful, code duplication everywhere
Registering the delegate at composition root / constructor injection? read this first
If constructor injected and using mutable entity, it can lead to stateful interface
Example for point no.4:
Below example only showing how constructor injected delegate with mutable entity can lead to stateful implementation.
public class Employee
{
public string Name { get; set; }
}
public class EvilDeleg
{
public EvilDeleg(Action<Employee> act)
{
this.act = act;
}
Action<Employee> act;
public void DoSomething(Employee emp)
{
Console.WriteLine(emp.Name); // resulting in "First"
emp.Name = " Evil";
act(emp);
Console.WriteLine(emp.Name); // resulting in " Evil Second"
}
}
public class TestStatefulInterface
{
public void ConsumeEvilDeleg()
{
Employee emp = new Employee();
EvilDeleg deleg = new EvilDeleg(k => k.Name = k.Name + " Second");
emp.Name = "First";
deleg.DoSomething(emp);
Console.WriteLine(emp.Name); // resulting in " Evil Second"
}
}
So, when is it appropriate for using the delegate over one-method interface?
My 2 cents:
The code does not have business-related code. You want to control the business aspect of your system, and having it anonymous to be controlled can be a pain
The code most likely have UI / DB - specific implementation. Such as conversion from DataTable to Entity, or Entity to UI ViewModel
It is trivial and do not need unit test
It is being injected in the method, not constructor, otherwise do not use mutable structure as input, or just use non-parameter delegate
Additionaly, Mark Seeman states in his blog that said:
only works as long as you only need to abstract a single method. As
soon as your abstraction needs a second method, you will need to
introduce a proper interface or, preferably, an abstract base class.
Ok, it turned out that the answer is BIG FAT NO, one cannot use delegates instead of single method interfaces for 2 fundamental reasons:
C# doesn't support recursive anonymous functions.
There are not type aliases in C#, so the signatures of functions quickly become hideous and unmanageable.
Bad luck.

Is there a better design option?

Disclaimer: I would love to be using dependency injection on this
project and have a loosely coupled interface-based design across the board, but use of dependency-injection has been shot down in this project. Also SOLID design principles (and design patterns in general) are something foreign where I work and I'm new to many of them myself. So take that into
consideration when suggesting a better design to this problem.
Here is a simplified version of the code I'm working on, and as such it might seem contrived. If so I apologize. Consider the following classes:
// Foo is a class that wraps underlying functionality from another
// assembly to create a simplified API. Think of this as a service layer class,
// a facade-like wrapper. It contains a helper class that is specific to
// foo. Other AbstractFoo implementations have their own helpers.
public class Foo : AbstractFoo
{
private readonly DefaultHelper helper;
public override DefaultHelper Helper { get { return helper; } }
public Foo()
{
helper = new Helper("custom stuff");
}
public override void Operation1(string value)
{
Console.WriteLine("Operation1 using " + value);
}
public override void Operation2()
{
Console.WriteLine("Operation2");
}
}
// Helper derives from a default implementation and allows us to
// override it's methods to do things specific for the class that
// holds this helper. Sometimes we use a custom helper, sometimes
// we use the default one.
public class Helper : DefaultHelper
{
private readonly string customStuff;
public Helper(string value)
{
customStuff = value;
}
public override void DoSomethingHelpful()
{
Console.WriteLine("I was helpful using " + customStuff);
}
}
Say these two class are used as follows:
// foo referenced and used in one part of code
var foo = new Foo();
foo.Operation2(); // or foo.Operation1();
// some other point in the program where we don't have a reference to foo
// but do have a reference to the helper
helper.DoSomethingHelpful();
However I now find out that I also need to perform foo.Operation1 in some implementations of helper.DoSomethingHelpful();? Potential workarounds I thought of would be:
Have foo and helper have a bidirectional relationship. So that in DoSomethingHelpful we can call foo.Operation2
Have foo implement IHelp interface and move the "helper" code into foo
Use delegation and pass the method Operation2 as an Action<string> delegate into the constructor of Helper.
None of these approaches seem to be ideal (though I've pretty much determined I don't like option 1 and am worried about maintainability with option 3 if we find out later we need to pass in more delegates). This makes me wonder if there is a problem with the initial design of the Helper/Foo combo. Thoughts?
How about a casual ("uses") relationship:
public class Helper : DefaultHelper
{
private readonly string customStuff;
public Helper(string value)
{
customStuff = value;
}
public override void DoSomethingHelpful(AbstractFoo foo)
{
foo.Operation1();
Console.WriteLine("I was helpful using " + customStuff);
}
}
So you modify the abstract helper to expect a reference to the proper Foo implementation.
"None of these approaches seem to be ideal (though I've pretty much
determined I don't like option 1 and am worried about maintainability
with option 3 if we find out later we need to pass in more delegates).
This makes me wonder if there is a problem with the initial design of
the Helper/Foo combo."
You're exactly right - there IS a problem with the design of Helper and Foo. The basic Foo/Helper relationship as you initially described it is fine, and is a common pattern when you have to wrap other objects that you do not control. But then you say:
"What if I find out that I also need to perform foo.Operation1 in some
implementations of helper.DoSomethingHelpful();?"
This is where we have a problem. You started out describing a relationship where Foo is dependent on Helper; now you are describing a relationship where Helper is dependent on Foo. That immediately tells me that your dependency relationships are tangled up. Dependency relationships between objects should only go one way; in fact dependency injection relies on this.
I think you have what you need. Try not to design for the "just in case I need it later" and don't fix what is not broken. If in the future you need to use Operation1 from your helper, then add it as a dependency on the constructor (as you suggested), or just pass it to the method you are calling. It will depend on the scenario, and you will have it when you actually need something.
EDIT: changed the "Try not to design for the future" as it doesn't seem what I want to say.
EDIT again due changes in the question
You could so something like this:
helper.DoSomethingUsefulWith( foo );
so your helper method will receive the dependency it needs in order to work
I think all your solutions are good; they just offer different capabilities. These differences don't matter too much now but are likely to in the future.
You prefer the second one, and your instincts are the best guide here, you knowing more than the rest of us about your code's future. I like your second solution the best just because it gets rid of a class and is simpler. Due to it's simplicity, if you have to do something else later, you won't have to throw away a lot of work.
The first method lets you play games with different Helper (IHelper?) instances and subclasses. The last method adds a lot of flexibility to Helper. (Although it may add so much you don't need Helper, just the method you're passing to it.) You can switch to using them later if either seems to solve more of the future's unguessed problems.

Is there a way to apply an attribute to a method that executes first?

Without using a library like PostSharp, is there a way to set up a custom attribute that I can have logic in that when attached to a method, will execute PRIOR to entering that method?
No; attributed are not intended to inject code. Tools like postsharp get around that with smoke and mirrors, but without that: no. Another option might be a decorator pattern,
perhaps dynamically implementing an interface (not trivial by any means). However, adding a utility method-call to the top of the method(s) is much simpler, and presumably fine since if you have access to add attributes you have access to add a method-call.
Or put another way: tools like postsharp exist precicely because this doesn't exist out-of-the-box.
// poor man's aspect oriented programming
public void Foo() {
SomeUtility.DoSomething();
// real code
}
In some cases, subclassing may be useful, especially if the subclass is done at runtime (meta-programming):
class YouWriteThisAtRuntimeWithTypeBuilder : YourType {
public override void Foo() {
SomeUtility.DoSomething();
base.Foo();
}
}

Is there a way to hide/show certain methods when instantiating an object?

This question came to mind while I was writing a class that iterates over a list, with methods next() and previous() that will continuously loop (e.g. if at the last object, return it, and then reset index to 0)
In the constructor I was pondering adding a boolean variable, which if true would just act like a regular iterator with only next() methods and no looping. In this case, having the method previous() would make no sense. So I'm curious, is it possible to hide the previous() method in this case. Is it possible to achieve this somehow in Java or C#?.
What about other languages?
C#
It is possible by making the two methods part of two different interfaces, and casting the object to one of the two interfaces. For example:
interface ILoopingIterator
{
void Next();
void Previous();
}
interface INonLoopingIterator
{
void Next();
}
class PlaysItBothWays : ILoopingIterator, INonLoopingIterator
{
void ILoopingIterator.Next()
{
this.NextCore();
}
void ILoopingIterator.Previous()
{
// since this code will never be shared anyway, put it here
}
void INonLoopingIterator.Next()
{
this.NextCore();
}
private void NextCore()
{
// do stuff here; this method only exists so that code can be shared
}
}
Note that I have made the class implement both interfaces explicitly; this way, users of instances are forced to select which "mode" they want to use the class in. You could implement only one interface explicitly instead (providing a "default" mode that can be changed).
and now:
var looping = (ILoopingIterator) new PlaysItBothWays(); // selects mode A
var nonLooping = (INonLoopingIterator) new PlaysItBothWays(); // selects mode B
Of course this does not stop anyone from casting the instance to the "other" interface if they want to, but if the programmer wants to subvert their own code they can also use reflection which allows much more than that.
Java
In Java, the above is not possible. You can come close by having the class expose methods that return instances of one of the two interfaces, and using the returned value. Of course then the object is really a factory and not a service provider, so that's feels like cheating on the problem.
class PlaysItBothWays
{
public ILoopingIterator asLooping() { return /* something */ }
public INonLoopingIterator asNonLooping() { return /* something else */ }
}
Rather than passing a boolean to a constructor, you should simply use inheritance.
Suppose you have a base iterator that supports only next(). If that's the only functionality you need, instantiate it.
To provide more functionality, inherit from this base iterator, make a class called TwoWayIterator or something like that, and provide a previous() method.
Both of these classes will share a common super class, so you can treat them as one, and you can hide the previous() method by treating an instance as its base class.
It is not possible to hide a method like that in a statically typed language. The best you can do is implement the method to throw an exception (or equivalent) if the method is called.
There are tricks that you can do to make it appear like the methods are not there. For instance, having the class implement two interfaces, and using different factory methods to create them. However, they don't work if the constructor is used directly, or if you want the choice to be determined by the value of a constructor or factory method parameter.
Not in Java. You can't "Hide" methods at runtime. I'd suggest you to create Two interfaces
, one with the next method and the other one extending the first one and adding the "previous" method. Then, you can have 2 factories methods to create an instance of one of these classes.
Please take a look to the Java "Iterator" class
interface Iterator<T> {
T next();
}
interface LoopingIterator<T> extends Iterator<T>{
T previous();
}
Then you can cast them. Similar to the previous C# answer
You can't hide class members at run time (well, not in C# anyway - not sure about Java). If you so worried about Previous() method being used in the context where it is not doing anything useful, then simply have it throw InvalidOperationException in that case.
It is also worth noting that .NET already has standard "iterator" interface. It is called IEnumerable (and generic version IEnumerable<T>) and is forward-only.

How to implement saving/loading interface with parameterized constructor?

I know interfaces cannot define constructors. Here's what I wish I could do:
public interface SavableObject {
void Save(ObjectSaver saver);
SavableObject(ObjectLoader loader); //This, obviously, doesn't work
}
//Loading an object inside ObjectLoader:
T LoadObject<T>() where T : SavableObject {
return (T)Activator.CreateInstance(typeof(T), this);
}
And I could do this if I took out the line that didn't work, and there would just be a runtime error when trying to load (or possibly save, if I put an assert in there) the object if it didn't have the constructor. I'm just wondering if there's any way to require a class to have a particular constructor that can be used with the Activator. Can I use a custom attribute somehow, and require that attribute to be on the class? Or must I rely on runtime checks to load and save data?
I know I could have a parameterless constructor and a Load(ObjectLoader) method but I don't necessarily want to have a parameterless constructor available to abuse for other purposes.
what about ISerializable?
In brief I suggest you use generics as most factories do.
public interface SavableObject<T> : where T : new
{
void Save(IObjectSaver<T> saver);
SavableObject<T> Load(ObjectLoader loader); //This, obviously, doesn't work
}
However, you seem to have turned it on it head. The class is doing what factory must do. So I do not think it is such a good idea to pass the factory to the entity itself and that is part of the problem you are experiencing in the design.
If you are not afraid of using Reflection, like Activator that you have shown, you can do little trick I tend to use:
Make parameterless constructor that is protected
Make Load method, that is also protected (or private, I tend to use virtual protected so I support inheritance)
Create new object using this non-public constructor (through reflection - you can't create instance of your class "just like that" using new operator)
Invoke load method (also using reflection - no one will call it later).
I don't know if this will work for you, but I used that method when I needed to deserialize pretty big game state and it was pretty fast, eventhough all this reflection (for many reasons I did not wanted to use built-in serialization methods and Factory Pattern wouldn't do, so I tend to treat this method as something that may be useful if other methods fail, on the other hand, if I could - I would probably use built-in serialization for simplicity).
How about adding a property on your interface:
public interface SavableObject
{
void Save(ObjectSaver saver);
ObjectLoader ObjectLoader {get; set;}
}
Then in your factory:
T LoadObject<T>() where T : SavableObject
{
var result = (T)Activator.CreateInstance(typeof(T));
result.ObjectLoader = this;
return result;
}
Based on your question and comments.
I think you should do it at runtime using reflection.
Combining constructors and interfaces is ilogical from its core. Interface is about what concrete instance can do, not how to initialize it. This can only be achived using abstract class.
Maybe using factory to create instance of the class?
Also I don't think you can get better speed than default ISerializable implementation. Unless you are .NET GURU and have years of time for it.
Short answer: It's not possible, I guess. There are no attributes or generalizations I can use to require a specific kind of constructor on a class.

Categories

Resources