I have a need to implement a complex aspect which needs to be able to introduce an interface, as well as several pointcuts. I'm not sure how to do this.
My goal is to intercept some field setters on a class, so that I can introduce some behaviour (via event handlers on the decorated fields). I want to transform some data, and then raise an event which is declared on a specific interface, so I want to introduce this interface to the class which contains these fields.
The simplest concept would be a container which captures all events on its children and transforms them into a single external event on the container class.
So, I know how to introduce method pointcuts using LocationInterceptionAspect;
public override void OnSetValue(LocationInterceptionArgs args)
{
// attach event handler to args.Value.SomeEvent,
}
And also how to introduce interfaces/methods with an InstanceLevelAspect.
But not how to combine the 2 into a single aspect.
I can't simply introduce an interface or member inside a LocationInterceptionAspect, as the scope is the location, not the containing type, and it won't compile.
I could always separate this into 2 aspects, however this means each aspect will not function independently, and I'd have to ensure both are always applied together.
It appears that I can add an OnLocationSetValueAdvice (via attributes) to an InstanceLevelAspect, and this works.
[IntroduceInterface(typeof(IMyInterface)]
public class CustomAspect : InstanceLevelAspect
{
[OnLocationSetValueAdvice]
[MulticastPointcut(Targets = MulticastTargets.Field, Attributes = MulticastAttributes.Instance)]
public void OnSetValue(LocationInterceptionArgs args)
{
...
}
}
Related
I'm facing a design issue where I'm trying to call all objects that implement a certain interface IInitialize that has a method "Initialize".
"IInitialize" can implement several classes like GameManager, Player, Enemy etc.
However IInitialize can be also implemented in other classes that don't have to Initialize themselves in that exact moment when I want to let's say restart the game, so I need some sort of "categorization" of Init calls so other classes don't get called when I don't need them to be.
So here I have few options like creating another empty subclass of "IInitialize" and just make a call to "Initialize" through this type. All classes that Implement subclass will get this call. (it works, but it is a correct approach - not code smell?).
Another option is to create a generic "Initialize" interface and just pass the string or something similar to distinguish between calls.
So to recap: I implement the interface to various classes, let's say "ILife" which has a method "Die" to implement in the class. However I don't want all objects of type to die at a certain time, just the required ones.
Any other ideas or am I going in the wrong direction?
Thanks in advance!
Since this question is tagged C# I will use C# in the code examples. But the solutions apply to any object oriented language as well.
This is a question of design. You have many options to solve this. I will show three:
1. Use separate interfaces that serve a certain scenarios
interface IInitializable
{
void Initialize();
}
interface IGameStartInitializable : IInitialize
{
}
If both interfaces share absolutely the same members, this solution or especially the IGameStartInitializable inteface would have the character of a tagging interface and a proof of bad design.
I don't recommend this solution.
2. Use separate containers for the objects
public List<IInitialize> DefaultInitializables = new List<IInitialize>();
public List<IInitialize> GameStartupInitializables = new List<IInitialize>();
Now that you added each objects to the corresponding collection you can easily iterate over them. This is more elegant than the first solution.
3. Use events
Introducing a GameStarting and GameStarted events would delegate the initialization to the type itself. Let the corresponding instances of type IInitialize subscribe to this event. Their event handler will invoke IInitialize.Initialize() on themselves.
class Player : IInitialize
{
public Player(IGameEngine gameEngine)
{
gameEngine.Starting += InitializeOnGameStarting;
}
private void InitializeOnGameStarting(object sender, EventArgs e)
{
gameEngine.Starting -= InitializeOnGameStarting;
// Invoke the implemented member of IInitialize
Initialize();
}
}
This is the most elegant way. It is extensible since every implementation handles it's own initialization. No filtering or sorting (add implementations to the right collection) and iterations necessary.
I'm adding a replaying feature to my game. Having this feature, I can capture user's input to the game and feed them back to Unity later on for replaying the game. But the design of VRStandardAssets.Utils.VRInput class prevents me to mimic user inputs.
This class does not provide any public method to make it possible to trigger its events (e.g. OnClick or OnDoubleClick events) programmatically. So I decided to create a derived class from it and write my own public methods to trigger the events. This strategy failed because VRInput's methods are private meaning that I cannot invoke them from a derived class.
It is recommended for this type of classes to provide a protected virtual void On[eventName](subclassOfEventArgs e) method to provide a way for a derived class to handle the event using an override but this class does not have it (why so restrictive?). I guess it's a poor design from Unity. This poor design also makes it hard to write unit/integration tests.
Am I missing something here? Can I still do something to trick other classes to think they are dealing with VRInput class while replaying the game?
In fact you can trigger theses events (OnClick, OnDoubleClick or any other events) from another class and without using reflection using this clever hack (Inspired by this article):
C# is not really type safe so you can share the same memory location. First declare a class with two fields that share the same memory space:
[StructLayout(LayoutKind.Explicit)]
public class OverlapEvents
{
[FieldOffset(0)]
public VRInput Source;
[FieldOffset(0)]
public EventCapture Target;
}
Then you can declare a new class that will intercept and call the other event:
public class EventCapture
{
public event Action OnClick;
public void SimulateClick()
{
InvokeClicked();
}
// This method will call the event from VRInput!
private void InvokeClicked()
{
var handler = OnClick;
if (handler != null)
handler();
}
}
Then finally register it and call it:
public static void Main()
{
input = GetComponent<VRInput>();
// Overlap the event
var o = new OverlapEvents { Source = input };
// You can now call the event! (Note how Target should be null but is of type VRInput)
o.Target.SimulateClick();
}
Here is a simple dotNetFiddle that show it working (at least outside of unity)
It is recommended for this type of classes to provide a protected virtual void On[eventName](subclassOfEventArgs e) method to provide a way for a derived class to handle the event using an override but this class does not have it (why so restrictive?). I guess it's a poor design from Unity. This poor design also makes it hard to write unit/integration tests.
All code is good code. All code is also bad code. Depends on your evaluation criteria. Unity's developers probably didn't think about your use case. As another conflicting rule of thumb, software should also be as simple & rigid as possible, so anticipating subclassing without a known use case might be considered overengineering.
As for how you can work around this, see How do I raise an event via reflection in .NET/C#?
I am trying to implement the following in C# so that I can force initialization of certain event delegates and variables in the parent classes, or I would use interface's instead. Obviously the below is not syntax correct.
the concrete class is Class1 & class 2.
the idea being here MyClass Is a button and it is an Image and it is something else.
Edit: " I understand that selectable and others are not objects but states. what I really want to do is to write the code that maintains the selectable state in the appropriate method because it will be the same for all of them. i.e. On click event( click location) check if i was I clicked based on my bounding box, update state to selected. I am in XNA, which is a c# polling environment, and I'm attempting to make the GUI as event driven as possible, if that makes any sense? "
public abstract class Class1
{
private int NumberNeededForMethod;
private void methodThatOccursWhenEventHappens(int NumberNeededForMethod)
{
// stuff using NumberNeededForMethod;
}
private Class1(int NumberNeededForMethod)
{
MethodDelegate += methodThatOccursWhenEventHappens(int
NumberNeededForMethod)
;
}
}
public abstract class Class2
{
private int NumberNeededForMethod2;
private void methodThatOccursWhenEventHappens2(int NumberNeededForMethod2)
{
// stuff using NumberNeededForMethod2;
}
Class2(int NumberNeededForMethod2)
{
MethodDelegate += methodThatOccursWhenEventHappens(int NumberNeededForMethod2);
}
}
public class ClassThatIsBothClass1andClass2: Class1, Class2
{
ClassThatIsBothClass1andClass2( int NumberNeededForMethod1, int NumberNeededForMethod2) : Class1(NumberNeededForMethod1),Class2(NumberNeededForMethod2)
{
}
}
You can use composition to create a class which wraps class1 and class2 and is the thing that responds to the event raised by your button.
First, of course, C# does not support multiple inheritance, so whatever polymorphism you implement will have to be accomplished using interfaces and composition.
Referring to this comment: Draggable, Selectable and Ownable are attributes of an object.
Image and Button, on the other hand, are objects.
A Button cannot be an Ownable.
But a Button can be Ownable, Draggable or Selectable. What I wonder is whether those attributes aren't just properties on a single IAshtonControl interface?
A Button can conceivably also be an Image. That makes perfect sense.
Because C# lacks multiple inheritance, you simply cannot create an AshtonButton class that derives from both Button and Image base classes.
One thing you can do is create an AshtonButton class that implements the IAshtonControl interface, and the implementation for that interface can delegate to a private instance of a worker class that does whatever work is common to all IAshtonControl instances.
Or you could have separate IOwnable, IDraggable and ISelectable interfaces if that is what is required.
Either way, it becomes possible to truthfully make the statement that AshtonButton is an IAshtonControl, is ownable, is draggable, is selectable. Those things might have different meanings (different behavior/visual effects) for different controls, or they might not, but you would hide those implementation details behind the interface(s) so that you could programmatically treat each object the same way regardless of its implementation.
It is important to separate the object from its attributes, because that affects the way you think about the problem. Draggable is not a thing, it is a characteristic of a thing.
But if your goal is to have a Button that is also an Image, some type of composition or delegation is the way to accomplish that. If you have a IAshtonImage interface, then you would implement that on both the AshtonImage class, and on the AshtonImageButton class. Then you have an internal instance (composition) of the AshtonImage class, within the AshtonImageButton class, and delegate calls to the IAshtonImage members through to the private (composed) AshtonImage instance, and so on.
I've got a couple of classes that form a too-complicated object graph. Here's a peek at a smaller scenario. Assume INotifyPropertyChanged is in place.
class A
{
public InternalType InterestingProperty { get; set; }
}
class B
{
public A Component { get; set; }
}
My helper class watches for these events and updates its properties when the properties of the objects change. It does this so some other class that's interested in about a dozen properties on as many objects are easily accessible. This is all packed in a framework that has several variants, so inheritance is in play.
I've finished the first scenario, and ended up with a concrete class like this:
class ScenarioOnePropertySpy
{
protected ScenarioOne PropertySpy(Foo thingToMonitor)
{
_thingToMonitor = thingToMonitor;
RegisterForEvents()
}
public B InterestingB { get; }
protected RegisterForEvents()
{
// * Register for _thingToMonitor propertyChanged if first time.
// * If B is different, unregister the old and register the new.
// * If B hasn't been set yet register for PropertyChanged on it.
// * If B.Component isn't the same as last time unregister the
// old and register the new.
}
protected Update()
{
// Some monitored object changed; refresh property values and
// update events in case some monitored object was replaced.
B = _thingToMonitor.B;
RegisterForEvents()
}
private Handle_PropertyChanged(...) { Update(); }
}
It's icky event registration, but moving that ugliness out of the class that wants to know about the properties is the purpose. Now I've moved on to scenario 2 that monitors different objects/properties and used my concrete class as a guide for an abstract one:
abstract class PropertySpy
{
protected PropertySpy(FooBase thingToMonitor)
{
_thingToMonitor = thingToMonitor;
RegisterForEvents()
}
protected abstract void RegisterForEvents()
// ...
}
Whoops. I've got a virtual method call in the constructor. In theory it's safe for all of my scenarios, but the R# warning keeps digging at me. I'm sure if I move forward one day it's going to cause a problem that'll take a while to figure out. That method's definitely going to need to work with properties on the derived types.
I could drop the method and force derived types to do the event management themselves. That'd defeat the purpose for the base class. And someone would forget to follow the contract and it'd turn into a support incident; I spend enough time writing documentation as it is. Another one I thought of was making RegisterForEvents() publich and requiring users to call it after construction. That "create then initialize" pattern stinks in .NET and people always forget. Currently I'm toying with the notion of another class that does the event registration that's injected via the constructor. Then derived classes can provide that class to achieve the same effect as a virtual method without the dangers. But the thing doing the registration would need practically the same property interface as PropertySpy; it seems tedious but I guess "ugly and works" is better than what I've got.
Anything I'm missing? I'll even take "it's a warning, not a rule" as an answer if the argument is convincing.
Your scenario seems complicated enough to consider a completely different approach to class instantiation. What about using a factory to construct property spies?
public class PropertySpyFactory<T> where T : PropertySpy, new()
{
public static T Create()
{
T result = new T();
// … whatever initialization needs to be done goes here …
result.RegisterForEvents();
return result;
}
}
ScenarioOnePropertySpy spy = PropertySpyFactory<ScenarioOnePropertySpy>.Create();
It's salvagable in the code, instance initialization can be extended easily, and once you turn to an IoC it will feel quite natural and not much refactoring will be needed.
UPDATE: One another option in case a) your spy hierarchy is flat enough and b) you don't need to use a common ancestor or you can substitute it with an interface:
public abstract class PropertySpy<T> where T : PropertySpy, new()
{
public static T Create()
{
T result = new T();
// … whatever initialization needs to be done goes here …
result.RegisterForEvents();
return result;
}
…
}
public class ScenarioOnePropertySpy : PropertySpy<ScenarioOnePropertySpy>
{
…
}
ScenarioOnePropertySpy spy = ScenarioOnePropertySpy.Create();
In other words, the factory method is located right within the common ancestor. The drawback of this approach is that it isn't that orthogonal (the factory isn't separated from the classes being constructed) and hence less extensible and flexible. However, in certain cases may be a valid option.
Last but not least, you can create a factory method in each class again. The advantage is you can keep constructors protected and hence force users to use factory methods instead of direct instantiation.
The key issue I believe is that by the time the virtual method is called, your subclass constructor and initializers have not executed yet. So, in your overridden method, your subclass may not have all the things you expect to be initialized initialized.
Is there a neat way to make several classes (which say derive from 1 interface), to each perform a same action? Think of http modules in ASP.NET which serve each request (Each the key word) - is there a way to perform some common action on derived types? Reflection may be one way, though I would be interested in a way at a base class level.
Thanks
Not with only an interface; you'd want an abstract class in the middle there:
abstract class Whatever : IFooable {
public virtual void Do () {
PreDo();
}
protected abstract void PreDo();
}
Then you call Do, and PreDo is automatically called first on all implementing types.
(Edit: Just to be clear, I made Do virtual so this means if you re-implement it you should call base.Do() as the first thing, just to ensure that it actually calls the parent method).
If your classes all derive from a common base class, you could put this logic in your common base class.
If I understand what you are asking correctly, then perhaps an event handler is the way to go?
If you need a bunch of objects to respond to some action, then events (also called "message passing") is the way to go.
Something like this?
class Foo
{
public event EventHandler PerformAction;
private void OnActionNeeded()
{
// A bunch of Bars need to do something important now.
if (PerformAction != null)
PerformAction.Invoke();
}
}
class Bar
{
public Bar(Foo fooToWatch)
{
fooToWatch.PerformAction += new EventHandler(Foo_PerformAction);
}
void Foo_PerformAction(object sender, EventArgs e)
{
// Do that voodoo that you do here.
}
}
May not be a complete answer but I am tempted to think in terms of AOP and attributes.
some references:
http://www.codeproject.com/KB/cs/ps-custom-attributes-1.aspx
http://www.postsharp.org/contributions/documentation/removing-duplicate-code-in-functions
The Template Method design pattern may apply to what you're asking.
http://www.dofactory.com/Patterns/PatternTemplate.aspx
The overall point of designing an interface is to provide a protocol between two components and hide the implementation part.
The interfaces serve as a communication medium.
And what you are asking seem to be specific to implementaion.
Which can be cleanly handled using utility classes(singleton with the method)
I do not suggest to have abstract class in ur current scenario.