axon event handler in another class - eventhandler

I am using axon 2.3.1 , I have one aggregate class
public class MyAggregate extends AbstractAnnotatedAggregateRoot<MBAggregate> {
#AggregateIdentifier
private MyId Id;
private Circle circle;
EventDispatcher a=new EventDispatcher();
public MyAggregate() {
}
#CommandHandler
public MyAggregate(NewCommand command ) {
apply(new SmallEvent(command.getId(), command.getCircle()));
}
#CommandHandler
public MyAggregate( StoreDestinationsCommand command ) {
apply(new BigEvent(command.getId(), command.getCircle()));
}
//And some event handlers like
#EventHandler
public void onSmallEvent(SmallEvent event)
{
//Some logic here
}
#EventHandler
public void onBigEvent(BigEvent event)
{
//Some logic here
}
Now i want these event handlers to be contained in some other class and be called when that event get triggered
public class EventContainer {
private static final long serialVersionUID = -6640657879730853388L;
#EventHandler
public void onSmallEvent(SmallEvent event)
{
//Some logic here
}
#EventHandler
public void onBigEvent(BigEvent event)
{
//Some logic here
}
I tried putting them in another class but those events are not triggered.
Any idea how can i achieve this in AXON.
Thanks,

Short Answer: You need to tell Axon that your EventContainer class can handle events published to an Event Bus.
AnnotationEventListenerAdapter.subscribe(new EventContainer(), eventBus);
Longer Answer:
To achieve what you want to do, taking a step back to understand the building blocks provided by Axon to build a CQRS application would be of help...
Axon Framework is a framework that provides you with the building blocks to build a CQRS application. And a CQRS application, in layman's term is just an architecture that allows you to separate the part of your application that executes actions (write) and the part that display your application state (read).
To do this Axon provide a couple of building blocks.
1) CommandBus
The Command Bus is the component within Axon Framework that provides the mechanism of having commands routed to their respective Command Handlers. For example from your code sample, the #CommandHandler annotation on MyAggregate means that when NewCommand is created, your MyAggregate method would be called. The Command Bus is the component that makes this possible.
2) CommandGateway
Command GateWay is a component that exposes a more friendly API to the CommnadBus. While you are not required to use a Gateway to dispatch Commands, it is generally the easiest option to do so.
3) EventBus
The EventBus handles the dispatching mechanism for events. Much like the Command Bus does for Commands. So when you have apply(new BigEvent(command.getId(), command.getCircle())); which fires a BigEvent it is the Event Bus that is responsibly for making sure the necessary event handler is called. And in your case, the question you are asking is how to have the Event handlers defined in a separate Class and still have Axon be able to route the events to them.
This is quite straight forward. I would assume you are not using Spring and that you are manually setting up the Axon components together by hand and creating the NewCommand that triggers the SmallEvent that you want to handle in EventContainer#onSmallEvent method. A way to get this done may look like this:
public class FireCommandAndCaptureEventInAnotherClass {
public static void main(String[] args) {
// We use the simple Command Bus.
// There are different implementation available. For example axon provides a distributed command bus that can be used to distribute commands over multiple nodes
CommandBus commandBus = new SimpleCommandBus();
// The friendlier API to send commands with
CommandGateway commandGateway = new DefaultCommandGateway(commandBus);
// You may skip this as it may not pertain to your question but since we are using event sourcing, we need a place to store the events. we'll store Events on the FileSystem, in the "events" folder
EventStore eventStore = new FileSystemEventStore(new SimpleEventFileResolver(new File("./events")));
// a Simple Event Bus will do
EventBus eventBus = new SimpleEventBus();
// You may skip this as it may not pertain to your question but since event sourcing is used in this example we need to configure the repository: an event sourcing repository.
EventSourcingRepository<MyAggregate> repository = new EventSourcingRepository<MyAggregate>(MyAggregate.class,
eventStore);
// Sets the event bus to which newly stored events should be published
repository.setEventBus(eventBus);
// Tells Axon that MyAggregate can handle commands
AggregateAnnotationCommandHandler.subscribe(MyAggregate.class, repository, commandBus);
// This is the part you need. With this We register an event listener to be able to handle events published on to an event bus. In this case EventContainer.
AnnotationEventListenerAdapter.subscribe(new EventContainer(), eventBus);
// and let's send some Commands on the CommandBus.
commandGateway.send(id, circle);
}
}
With this setup, the handlers in the EventContainer would be able to react to events triggered from MyAggregate

Related

Does every WinRT/Windows Core thread have a Dispatcher?

We're providing a library that needs to run code on its own custom threads. Once done, I want these threads to call callbacks (event handlers) through a Dispatcher (System.Windows.Threading.Dispatcher). The library user shall use the Dispatcher to dispatch event handling to.
We could simply always dispatch on CoreApplication.MainView.CoreWindow.Dispatcher but not all programs (e.g. Windows 10 IoT Core apps) provide an UI and thus they lack a main window.
Can the user simply refer to System.Windows.Threading.Dispatcher.CurrentDispatcher to get his thread's Dispatcher? Or can't all threads have a Dispatcher?
Edit: Here's more context for this question. Hopefully it makes the question easier to grasp: https://github.com/getsenic/nuimo-windows/issues/2
For first, I'm not sure, that you should execute event handlers on UI thread, because only client knows if he needed access UI elements.
For second, before invoking CoreApplication.MainView property you can check CoreApplication.Views.Count > 0 (I'm not absolutely sure that it will work because currently I don't have device to test it).
And also you can solve this issue in another way: in constructor of you object save the SynchronizationContext of executing thread and then use it to raise events. It will work if your object instantiates from UI thread (in most cases it's true). That way you can completely refuse from Dispatcher.
public class NotifierExample
{
private readonly SynchronizationContext _synchronizationContext;
public event EventHandler SomethingHappened;
public NotifierExample()
{
_synchronizationContext = SynchronizationContext.Current;
}
public void Do()
{
Task.Factory.StartNew(() =>
{
//do something
OnSomethingHappened();
});
}
private void OnSomethingHappened()
{
if (_synchronizationContext != null)
{
_synchronizationContext.Post(o => RaiseSomethingHappened(), null);
}
else
{
RaiseSomethingHappened();
}
}
private void RaiseSomethingHappened()
{
var somethingHappened = SomethingHappened;
somethingHappened?.Invoke(this, EventArgs.Empty);
}
}
Or can't all threads have a Dispatcher?
Dispatcher threads are always tied to UI threads. IoT headless mode app does not have an UI so it does not have a Dispatcher thread.
Can the user simply refer to System.Windows.Threading.Dispatcher.CurrentDispatcher to get his thread's Dispatcher
System.Windows.Threading.Dispatcher.CurrentDispatcher is only supported in legacy .NET platform. The UWP alternative is CoreApplication.MainView.CoreWindow.Dispatcher as you pointed out.
If you want to to do async callbacks in Headless(without GUI) mode, you can probably refer to Task Parallel Library(TPL), the ContinueWhenAll ContinueWhenAny etc API... might well suits your needs. Refer to https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskfactory.aspx.

Deferring PropertyChanged events until view bindings setup complete

A number of our MVVMcross views depend remote services to fully display themselves. We typically kick this off a Task in ViewModel's Init() using to get it async. ViewModel properties are set in the Task upon completion, UI updated via PropertyChanged notifications.
Sometimes the remote data (and task) completes before the View has bound it's listeners and thus no property changed event is received.
This issue is touched on at async Init and Property Changed in MvvmCross but the solution feels like duplication of presentation logic.
We've had success buffering PropertyChanged notifications until the end of ViewDidLoad, but we'd like to turn below into a more generic solution by hooking into the MVX framework.
Is there a way to hook mvvmcross's view creation to fire our code off after viewDidLoad completes?
Base View Model
public abstract class BaseViewModel : MvxViewModel{
protected bool _deferPropertyChangedEvents = true;
private readonly List<PropertyChangedEventArgs> _deferedPropertyChangedEvents = new List<PropertyChangedEventArgs>();
public override void RaisePropertyChanged(PropertyChangedEventArgs changedArgs)
{
lock(_deferedPropertyChangedEvents){
if (!_deferPropertyChangedEvents)
{
base.RaisePropertyChanged(changedArgs);
}
else
{
// buffer it up
_deferedPropertyChangedEvents.Add(changedArgs);
}
}
}
public void EndDeferringPropertyChangedEvents()
{
lock(_deferedPropertyChangedEvents){
_deferPropertyChangedEvents = false;
// playback all buffered notifications
foreach (var e in _deferedPropertyChangedEvents)
{
RaisePropertyChanged(e);
}
_deferedPropertyChangedEvents.Clear();
}
}
}
Sample view
public class SomeView : MvxViewController
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
var bindings = this.CreateBindingSet<StopView, SomeViewModel>();
.....
bindings.Apply();
// plays back any PropertyChanged() notifications that were buffered
// up while the view was initializing
// ---> want to find a way to have MVX call this
ViewModel.EndDeferringPropertyChangedEvents();
}
}
As a simple answer, I believe your own line can easily be called using a BaseViewModel cast:
// ---> want to find a way to have MVX call this
((BaseViewModel)ViewModel).EndDeferringPropertyChangedEvents();
However, on a more technical note, I think it might be useful to further examine and understand why this Deferring code is necessary - to further take a look at what the underlying threading problems are.
There are a number of factors that are puzzling me at present::
During the line bindings.Apply(); all current bound property values should be transferred from the ViewModel to the View - so calling EndDeferringPropertyChangedEvents(); in the next line should (in theory) only rarely get different values.
Further, the default MvvmCross RaisePropertyChanged method changed notifications across to the UI thread. Because ViewDidLoad is also invoked on the UI thread, this means that any RaisePropertyChanged calls made on background threads during ViewDidLoad should all be automatically deferred until after ViewDidLoad has finished and the UI thread becomes available.
Looking at the MvxNotifyPropertyChanged code, the only potential gap I can see where mutli-threading might find a way through this automatic RaisePropertyChanged deferral is in this optimisation check:
// check for subscription before potentially causing a cross-threaded call
if (PropertyChanged == null)
return;
(from https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross/ViewModels/MvxNotifyPropertyChanged.cs#L76)
If your ViewModel Init method is also using async for it's Task management, then this async code should also be using the UI thread - so the "callback" of this async operation should also be marshalled back to the UI thread (and so shouldn't be executed during ViewDidLoad itself).
As I said, these factors are puzzling me - I don't have a definitive answer/explanation - sorry! But I'd love to see an example problem and to try to help solve it at a generic level.

How do I structure a command system using event in as3?

I've tried searching the answer beforehand but I don't know what keyword should I search to find what I wanted.
Here is the question.
I am trying to make a simple turn based strategy game with AS3. I have 2 classes being used:
The "Main" class for starting up the game
The "Castle" class that creates a castle with a function to dispatch an "Attack" Event .
When the game start the Main class (The main gameplay screen) will create 4 different instance of the Castle class. Each of those castle will have the option to attack other castles.
I would like to set up a system that functions like this:
Main class contains a event listener to hear for "Attack CastleX" (X is variable, it changes according to which castle is being attacked)
Castle will be dispatching event called maybe "Attack Castle#1" or "Attack Castle#2" to indicate which castle it wants to attack.
Main class then receives the "Attack Castle#1" or "Attack Castle#2" event. And decrease the Health Point of the targeted Castle.
My problem here is that i don't know how to set up an event listener that can listen to both the event "Attack Castle#1" and "Attack Castle#2" or "Attack Castle#3/4/5/6/7".
I have a feeling that I might have to use String for this purpose.
So basically you want to dispatch an event which has a property referring to the Castle you want to attack.
That's easy enough to achieve when you create your own event:
public class CastleEvent extends Event
{
public static const ATTACK:String = "attack";
// Linked to the castle.
public var castle:int;
public function CastleEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false):void
{
super(type, bubbles, cancelable);
}
}
When your Castle starts attacking:
var attack:CastleEvent = new CastleEvent(CastleEvent.ATTACK);
attack.castle = 2; // Specify the castle to attack.
dispatchEvent(attack);
And then the listener in the main class can deal with the appropriate Castle:
private function _manageAttack(e:CastleEvent):void
{
var targetCastle:int = e.castle;
// Do stuff to the targetCastle.
//
//
}

Application Design Patterns AS3

just thought I would share something I have found to help delivering data across an application I am wondering what others think about this I wanted to have a way to capture event bubbling up back down to other components but in a way that it would make it easy to use anywhere in may app so this is what i came up with.
I Extend the Application class and wrap in an abstract function registering a function of any component anywhere and capture it at the top most level and pass to where ever i chose to.
public class AxApplication extends Application
{
public var ___registeredEvents:Array = new Array();
public var ___registeredFunctions:Array = new Array();
function AxApplication()
{
super();
}
public function localRegisterForEvent(e:Event,func:*,caller:*):void
{
caller.addEventListener(e.type,localCallerEventHandler,true,3);
caller.addEventListener(e.type,localCallerEventHandler,false,3);
___registeredEvents.push(e);
___registeredFunctions.push(func);
}
public function localCallerEventHandler(e:*):void
{
if(e!=null)
{
for(var i:int = 0 ; i< ___registeredEvents.length; i++)
{
if(e.type == ___registeredEvents[i].type)
{
___registeredFunctions[i](e);
//the registered function gets called
//there no garbage collection implemented!
}
}
}
}
}
I think that is not a very useful solution. Why? Because you scatter AxApplication references around the application. Views and Model instance don't need any references to the application at all. It would be better to to implement a controller layer which uses a simple eventBus property, which could look like:
private static const _EVENT_BUS:IEventDispatcher = FlexGlobals.topLevelApplication;
protected final function eventBus():IEventDispatcher {
return _EVENT_BUS;
}
If you implement a base view controller/mediator (depending from which framework you're coming), you don't have any reference to non-framework classes at all, which makes it highly reusable. It is just a simple reuse of the Application singleton which you use to dispatch system wide events. You register listeners in the view controller/mediator and update the views or models accordingly. RobotLegs for example uses a system wide event dispatcher as well.
Why not just using the parentApplication approach? Because you can't implement tests (the generated test-runner of IDEs won't extend your AxApplication) or just yank the components/models in a different application - that is basically not possible.

How to use Behavior class with Swing events?

I'm writing code for a 3D graph, and I want the scene graph to update when the user presses a JButton. I'm trying to use a Behavior class, but I can't find any information on using swing events to wake up the behavior. I would REALLY appreciate any help! Thank you!!
You can use a special behavior object which contains a queue of Runnables. You can then post runnables to the behaviour and wake it up. You will have to sort out proper synchronisation so the behaviour only goes to sleep when there are no more commands in the queue, but it should work.
Make the class into a singleton to be able to run Runnable's inside the BehaviorScheduler, analogous to the SwingUtilities.invokeLater() method.
public class ThreadTransferBehavior extends Behavior {
private final static int POST_ID = 9997;
private final WakeupOnBehaviorPost m_wakeupPost = new WakeupOnBehaviorPost(this, POST_ID);
private final Stack<Runnable> commands;
public synchronized void processStimulus(Enumeration i) {
while(!commands.isEmpty()) commands.pop().run();
wakeupOn(m_wakeupPost);
}
public synchronized void queueCommand(Runnable r) {
commands.push(r);
postId(POST_ID);
}
}