I have been playing along with AOP for years, but didnt become 100% satisfied with the solutions.
AOP Frameworks with runtime weaving, like Spring.AOP, cannot change the interface of a class.
With post compile time Frameworks like Postsharp (anyone knows someone else ?) you can.
Check this sample out, it adds INotifyPropertyChanged implementation to your class. -> http://www.postsharp.net/model/inotifypropertychanged
This AOP feature is really great, but you run in troubles very soon...
If you want to access the new Interface within the hosting assembly, you cannot compile,
because the interface is added AFTER compilation.
so you get a "PropertyChanged is not defined"-error.
So you have to ugly workaround this, by seperating the classes into another assembly, so you can use those AOP advantages.
I remember, i ran into the same "Post compile time"-troubles using a T4-Template that generates source code, based on the reflected infos of a assembly. OK so post compile time is sometimes too late...
What i am looking for is a solution, where the source code of the class is parsed via a visual studio user defined tool, und then generates the code in a C# file, in a partial class.
(so all AOP applied classes have to be partial)
So its kind of "Pre-Compile-Time AOP".
This should definitly be possible, and could be done via using NRefactory as Code Parser.
Furthermore, Visual Studio would like this much more, than a post-compile modification.
So this solution eliminates disadvantages of post compile time weavers.
but does not give you all the features of AOP. But together with an AOP-Framework, this should be awsome.
Does anyone know a framework like this, or a discussion ?!
what do you think ?
kind regards, thomas
since you and I have already been corresponding on using SNAP as a viable alternative, I thought I'd post a summary of our discussion here for the benefit of those who are looking for a similar solution.
In short, SNAP provides a runtime AOP framework that doesn't change your code in any way. There's no post-compile step, just runtime interception which is predictable and easy to use.
What your are looking for is pMixins. It's still in beta, but it does exactly what you are looking for: design-time weaving. AOP code is generated into a partial code-behind class so it's available at design-time.
So this means you can do this in one file and the compiler is happy, visual studio is happy, resharper is happy:
Define an interface:
public interface ISomeInterface
{
void SomeMethod();
}
Create an implementation of the interface (I call this a Mixin):
public class SomeInterfaceImplementation : ISomeInterface
{
public void SomeMethod()
{
//implementation
}
}
Define a Target file (which will consume the Mixin):
[pMixin(Mixin = typeof(SomeInterfaceImplementation))]
public partial class Target { }
Let's create a utility class that works with SomeInterface and SomeInterfaceImplementation:
public class Utility
{
public void DoSomeWorkOnSomeInterface(ISomeInterface obj)
{
obj.SomeMethod();
}
public void DoSomeWorkOnImplementation(SomeInterfaceImplementation obj)
{
obj.SomeMethod();
}
}
And now let's see it all work together:
class Program
{
private static void Main(string[] args)
{
//Call the mixed in method
new Target().SomeMethod();
//Target implements ISomeInterface is code-behind
new Utility().DoSomeWorkOnSomeInterface(new Target());
//Target has an implicit conversion operator to
//SomeInterfaceImplementation in code-behind
new Utility().DoSomeWorkOnImplementation(new Target());
}
}
The reason this works is because as soon as you save the file, the pMixins code generator immediately does design-time weaving and updates the code-behind file. It adds the SomeMethod directly to Target, updates Target's class definition to implement ISomeInterface and creates conversion operators.
Disclosure: I am on the pMixins development team.
In the case of PostSharp, you can access an interface introduced at post-compile-time by using the method Post.Cast, which is a kind of cast operator that is verified at post-compile-time. See http://doc.postsharp.net/postsharp-3.0/Content.aspx/PostSharp-3.0.chm/html/M_PostSharp_Post_Cast__2.htm for documentation.
Related
I've founded the OnMethodBoundaryAspect attribute in the PostSharp library. It can intercept entry and exit from method like this:
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method, Inheritance = MulticastInheritance.Multicast)]
public class InterceptAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{ }
public override void OnExit(MethodExecutionArgs args)
{ }
}
public class A
{
[Intercept]
public void foo() { }
}
And my question is "How does it work?" What should I do to write my own attribute, that will be able to intercept entry and exit from method (without PostSharp using ofcourse)?
First of all, I'd recommend reading following documentation for internal workings (the "how does it work" sections and others). Basically, the attributes are translated into relevant code at the build time (actually, mostly after the build but still while building). There's a notion of MSBuild task that specifies the code to be run during the build process. The code executes after the compilation is done and looks for specific attributes (like InterceptAttribute) and may perform changes to the compiled code. Runtime edits to the code may be executed while using Mono.Cecil library (it allows to inject/remove IL code). Once again, to clarify:
The code is built with attributes assigned.
During the build, specific code is called per BuildTasks written
BuildTasks use reflection to find pieces of code that contain necessary attributes
BuildTasks use Mono.Cecil to inject code dynamically to those pieces found
Build is complete. Your compiled dll now contains not only the code written, but also the attributes changed into some code. I'd suggest looking at the assembly with ILSpy or similar decompilers to see the difference between your initial code and generated one.
I'd recommend looking at KindOfMagic codes to see how automatic INotifyPropertyChanged's RaisePropertyChanged is implemented as attribute. It provides valuable insights into creating custom aspects, though it may prove hard and tedious process.
Every so often, I run into a case where I want a collection of classes all to possess similar logic. For example, maybe I want both a Bird and an Airplane to be able to Fly(). If you're thinking "strategy pattern", I would agree, but even with strategy, it's sometimes impossible to avoid duplicating code.
For example, let's say the following apply (and this is very similar to a real situation I recently encountered):
Both Bird and Airplane need to hold an instance of an object that implements IFlyBehavior.
Both Bird and Airplane need to ask the IFlyBehavior instance to Fly() when OnReadyToFly() is called.
Both Bird and Airplane need to ask the IFlyBehavior instance to Land() when OnReadyToLand() is called.
OnReadyToFly() and OnReadyToLand() are private.
Bird inherits Animal and Airplane inherits PeopleMover.
Now, let's say we later add Moth, HotAirBalloon, and 16 other objects, and let's say they all follow the same pattern.
We're now going to need 20 copies of the following code:
private IFlyBehavior _flyBehavior;
private void OnReadyToFly()
{
_flyBehavior.Fly();
}
private void OnReadyToLand()
{
_flyBehavior.Land();
}
Two things I don't like about this:
It's not very DRY (the same nine lines of code are repeated over and over again). If we discovered a bug or added a BankRight() to IFlyBehavior, we would need to propogate the changes to all 20 classes.
There's not any way to enforce that all 20 classes implement this repetitive internal logic consistently. We can't use an interface because interfaces only permit public members. We can't use an abstract base class because the objects already inherit base classes, and C# doesn't allow multiple inheritance (and even if the classes didn't already inherit classes, we might later wish to add a new behavior that implements, say, ICrashable, so an abstract base class is not always going to be a viable solution).
What if...?
What if C# had a new construct, say pattern or template or [fill in your idea here], that worked like an interface, but allowed you to put private or protected access modifiers on the members? You would still need to provide an implementation for each class, but if your class implemented the PFlyable pattern, you would at least have a way to enforce that every class had the necessary boilerplate code to call Fly() and Land(). And, with a modern IDE like Visual Studio, you'd be able to automatically generate the code using the "Implement Pattern" command.
Personally, I think it would make more sense to just expand the meaning of interface to cover any contract, whether internal (private/protected) or external (public), but I suggested adding a whole new construct first because people seem to be very adamant about the meaning of the word "interface", and I didn't want semantics to become the focus of people's answers.
Questions:
Regardless of what you call it, I'd like to know whether the feature I'm suggesting here makes sense. Do we need some way to handle cases where we can't abstract away as much code as we'd like, due to the need for restrictive access modifiers or for reasons outside of the programmer's control?
Update
From AakashM's comment, I believe there is already a name for the feature I'm requesting: a Mixin. So, I guess my question can be shortened to: "Should C# allow Mixins?"
The problem you describe could be solved using the Visitor pattern (everything can be solved using the Visitor pattern, so beware! )
The visitor pattern lets you move the implementation logic towards a new class. That way you do not need a base class, and a visitor works extremely well over different inheritance trees.
To sum up:
New functionality does not need to be added to all different types
The call to the visitor can be pulled up to the root of each class hierarchy
For a reference, see the Visitor pattern
Cant we use extension methods for this
public static void OnReadyToFly(this IFlyBehavior flyBehavior)
{
_flyBehavior.Fly()
}
This mimics the functionality you wanted (or Mixins)
Visual Studio already offers this in 'poor mans form' with code snippets. Also, with the refactoring tools a la ReSharper (and maybe even the native refactoring support in Visual Studio), you get a long way in ensuring consistency.
[EDIT: I didn't think of Extension methods, this approach brings you even further (you only need to keep the _flyBehaviour as a private variable). This makes the rest of my answer probably obsolete...]
However; just for the sake of the discussion: how could this be improved? Here's my suggestion.
One could imagine something like the following to be supported by a future version of the C# compiler:
// keyword 'pattern' marks the code as eligible for inclusion in other classes
pattern WithFlyBehaviour
{
private IFlyBehavior_flyBehavior;
private void OnReadyToFly()
{
_flyBehavior.Fly();
}
[patternmethod]
private void OnReadyToLand()
{
_flyBehavior.Land();
}
}
Which you could use then something like:
// probably the attribute syntax can not be reused here, but you get the point
[UsePattern(FlyBehaviour)]
class FlyingAnimal
{
public void SetReadyToFly(bool ready)
{
_readyToFly = ready;
if (ready) OnReadyToFly(); // OnReadyToFly() callable, although not explicitly present in FlyingAnimal
}
}
Would this be an improvement? Probably. Is it really worth it? Maybe...
You just described aspect oriented programming.
One popular AOP implementation for C# seems to be PostSharp (Main site seems to be down/not working for me though, this is the direct "About" page).
To follow up on the comment: I'm not sure if PostSharp supports it, but I think you are talking about this part of AOP:
Inter-type declarations provide a way
to express crosscutting concerns
affecting the structure of modules.
Also known as open classes, this
enables programmers to declare in one
place members or parents of another
class, typically in order to combine
all the code related to a concern in
one aspect.
Could you get this sort of behavior by using the new ExpandoObject in .NET 4.0?
Scala traits were developed to address this kind of scenario. There's also some research to include traits in C#.
UPDATE: I created my own experiment to have roles in C#. Take a look.
I will use extension methods to implement the behaviour as the code shows.
Let Bird and Plane objects implement a property for IFlyBehavior object for an interface IFlyer
public interface IFlyer
{
public IFlyBehavior FlyBehavior
}
public Bird : IFlyer
{
public IFlyBehaviour FlyBehavior {get;set;}
}
public Airplane : IFlyer
{
public IFlyBehaviour FlyBehavior {get;set;}
}
Create an extension class for IFlyer
public IFlyerExtensions
{
public void OnReadyToFly(this IFlyer flyer)
{
flyer.FlyBehavior.Fly();
}
public void OnReadyToLand(this IFlyer flyer)
{
flyer.FlyBehavior.Land();
}
}
I'd like to override a class method without inheriting the base class because it'd take a lot of time and modifications and, therefore, more and more tests. It's like this:
class TestClass{
public void initialMethod(){
...
}
}
And somewhere on the code, I'd like to do something like this:
public testMethod()
{
return;
}
test(){
changeMethod(TestClass.initialMethod, testMethod);
}
And this changeMethod function would override the TestClass initialMethod so that it'd call testMethod instead.
Inheriting and overriding the method using normal practices is not an option, as this class A is a graphic component and, inhereting it (and changing it) would break lots of code.
Edit: We don't have the base code for the TestClass, so it's not an option to modify the code there defining the initialMethod as a delegate.
Edit 2: Since this is a graphical component, the designer added a lot of code automatically. If I were to inherit this code, I would have to replace all code added by the designer. That's why I wouldn't like to replace this component.
You need the Strategy pattern.
Main steps:
Create an interface with ie. Do() signature
Your initialMethod() should call a strategy.Do(), where strategy is type of your interface
Create a class that implements this interface. Do() is your testmethod now.
Inject into your main class an instance of this class
If the job it's not so big (let's say just a color replacement or something) then I agree with Jhonny D. Cano's solution with C# (anonymous)delegates.
Edit (after edit 2)
May - just as proof-of-concept - you should inherit the class and replace all references from base class to this new. Do this, and nothing else. If it works, you can think about the next steps (new methods or delegates etc.)
You need only a new checkout from your version control system, and if it maybe fails you can abandon it. It's worth trying.
Perhaps you can do it as a delegate.
class TestClass {
public Action myAction;
public void initialMethod(){
...
}
initialMethod
public TestClass() {
myAction = initialMethod;
}
}
and then on TestMethod
public testMethod()
{
return;
}
test() {
testClassInstance.myAction = testMethod;
}
I think your best bet might be to use a AOP framework like LinFu. There's a codeproject article explaining it:
Introducing LinFu, Part VI: LinFu.AOP – Pervasive Method Interception and Replacement for Sealed Types in Any .NET Language
If 'TestClass' is something you defined, you could replace the 'initialMethod' definition with a property and delegate which can then be set to any method with a given signature. (Even anonymous ones.)
class TestClass {
Action _myMethod;
Action MyMethod {
get { return _myMethod; }
set { _myMethod = value; }
}
var tc = new TestClass()
tc.MyMethod = () -> Console.WriteLine("Hello World!");
tc.MyMethod()
The above code is untested.
The short and simple answer is: if you can't adjust the base TestClass code, no, there's no way you can modify the class to replace a method by another. Once we started doing stuff like that, we'd be in a completely different kind of language, like JavaScript.
The longer answer is: it depends on who is calling the replaced method.
If it's other classes, see if you can't implement a Proxy in between them and the unmodifiable concrete class. Whether this is doable depends on whether that class implements interfaces, or is its own interface.
If it's the class itself, then your only option is to decompile and modify the class, at design time using Reflector (or equivalent tools), or at runtime using Reflection.Emit. However, you'd have to be hurting pretty badly to go this route, as it's sure to be painful and brittle.
Unfortunately you still haven't explained what you are trying do and why. Replacing methods on the go is powerful stuff in the languages that permit it directly... There might be mocking libraries that can be twisted sufficiently far to do the reflection stuff, but then you'd be skating on thin ice.
If you don't have the code use Extension Methods.
public void doSmth(this objectYOUWANT arg)
{
//Do Something
}
Here you use the principle Closed for Modification Open for Extension.
This will add functionality to the library you don't have the source code. It's very clean to do it this way.
Edition:
In FrameWork 3.5 there is something new called Extension Methods. These kind of methods adds functionality to a closed Assembly letting you Extend in functionality a closed dll/assembly.
To use this for example you have a dll that you import, that is called Graphics.dll (you have the reference on your project)
First of all you shoud create a new static class called for example Extension:
public static class Extensions
{
}
Second, you want to add extra functionality to a class contained in Graphics.dll named ChartGraph. You will do this:
public static class Extensions
{
public static void draw(this ChartGraph g)
{
// DO SOMETHING
}
}
Third, when you instantiate a new object from the graphics.dll you now will have the new method you have created:
ChartGraph myG = new ChartGraph();
myG.draw();
As you can see there you have added new functionality without much effort without recompiling the dll, this is good if you don't have the source code.
C# 3.0 Extension methods add extensions to the base Type making calling that method on all instances of that Type legal.
Now, JavaScript I know implements IDispatchEx through which it's possible to add methods to a specific instance.
So how do I add a set of methods to an 'instance' of a C# class? I know this is a Dynamic vs. Static Languages holy war territory. :) Let me clarify my intention is NOT that.
I just want to be able to add a set of events to an interface depending on the class implementing that interface.
I was able to do that using Generics
inteface ISample<T> { T SupportedEvents; }
class Sample : ISample<UIWidgetEvent> { }
class Sample2 : ISample<NonVisualUIWidget> { }
class UIWidgetEvent { public EventHandler Clicked; }
class NonVisualUIWidget {public EventHandler Expired;}
class TestSample
{
public void Test()
{
new Sample().SupportedEvents.Clicked += ...
new Sample2().SupportedEvents.Expired += ...
}
}
Then I didn't like SupportedEvents I want to be able to say
new Sample().Clicked +=...
Then I thought JavaScript (I know C# is not JS :))... AND IDispatchEx, IL Weaving, Reflection.Emit etc. etc. and thought may be there's a way to do this... [Design time support would be nice but I can live without]
Yes, I probably could do this "instance augmentation" with a Visitor pattern.
[Not sure if I could get the syntatic sugar though]
Comments?
Well, you could create a DynamicMethod instance for your "new" methods, but statically attaching them to an existing instance at runtime wouldn't work due to the fact it plain wouldn't compile.
You might (I haven't tried this) be able to emit the opcodes into an in-memory assembly, but that's about as far away from being "Syntactically sweet" as you can get (would involve a lot of reflection and InvokeMember calls, I would think)
It also might be worth looking into Extension Methods - although I've never tried attaching events or event-like methods via extension methods...and they are 3.5 only, so that may limit you.
The nicest looking, "pure C#" implementation is probably something very similar to what you've already got with the generic/interface setup...
Honestly, if you're looking for something with true "dynamic support" like this, I'd do this kind of stuff in a DLR-capable language (like IronPython) and call into it from your C# stuff.
I have a class with some abstract methods, but I want to be able to edit a subclass of that class in the designer. However, the designer can't edit the subclass unless it can create an instance of the parent class. So my plan is to replace the abstract methods with stubs and mark them as virtual - but then if I make another subclass, I won't get a compile-time error if I forget to implement them.
Is there a way to mark the methods so that they have to be implemented by subclasses, without marking them as abstract?
Well you could do some really messy code involving #if - i.e. in DEBUG it is virtual (for the designer), but in RELEASE it is abstract. A real pain to maintain, though.
But other than that: basically, no. If you want designer support it can't be abstract, so you are left with "virtual" (presumably with the base method throwing a NotImplementedException).
Of course, your unit tests will check that the methods have been implemented, yes? ;-p
Actually, it would probably be quite easy to test via generics - i.e. have a generic test method of the form:
[Test]
public void TestFoo() {
ActualTest<Foo>();
}
[Test]
public void TestBar() {
ActualTest<Bar>();
}
static void ActualTest<T>() where T : SomeBaseClass, new() {
T obj = new T();
Assert.blah something involving obj
}
You could use the reference to implementation idiom in your class.
public class DesignerHappy
{
private ADesignerHappyImp imp_;
public int MyMethod()
{
return imp_.MyMethod()
}
public int MyProperty
{
get { return imp_.MyProperty; }
set { imp_.MyProperty = value; }
}
}
public abstract class ADesignerHappyImp
{
public abstract int MyMethod();
public int MyProperty {get; set;}
}
DesignerHappy just exposes the interface you want but forwards all the calls to the implementation object. You extend the behavior by sub-classing ADesignerHappyImp, which forces you to implement all the abstract members.
You can provide a default implementation of ADesignerHappyImp, which is used to initialize DesignerHappy by default and expose a property that allows you to change the implementation.
Note that "DesignMode" is not set in the constructor. It's set after VS parses the InitializeComponents() method.
I know its not quite what you are after but you could make all of your stubs in the base class throw the NotImplementedException. Then if any of your subclasses have not overridden them you would get a runtime exception when the method in the base class gets called.
The Component class contains a boolean property called "DesignMode" which is very handy when you want your code to behave differently in the designer than at runtime. May be of some use in this case.
As a general rule, if there's no way in a language to do something that generally means that there's a good conceptual reason not to do it.
Sometimes this will be the fault of the language designers - but not often. Usually I find they know more about language design than I do ;-)
In this case you want a un-overridden virtual method to throw a compile time exception (rather and a run time one). Basically an abstract method then.
Making virtual methods behave like abstract ones is just going to create a world of confusion for you further down the line.
On the other hand, VS plug in design is often not quite at the same level (that's a little unfair, but certainly less rigour is applied than is at the language design stage - and rightly so). Some VS tools, like the class designer and current WPF editors, are nice ideas but not really complete - yet.
In the case that you're describing I think you have an argument not to use the class designer, not an argument to hack your code.
At some point (maybe in the next VS) they'll tidy up how the class designer deals with abstract classes, and then you'll have a hack with no idea why it was coded that way.
It should always be the last resort to hack your code to fit the designer, and when you do try to keep hacks minimal. I find that it's usually better to have concise, readable code that makes sense quickly over Byzantine code that works in the current broken tools.
To use ms as an example...
Microsoft does this with the user control templates in silverlight. #if is perfectly acceptable and it is doubtful the the tooling will work around it anytime soon. IMHO