I have a class called CommunicationManager which is responsible for communication with server.
It includes methods login() and onLoginResponse(). In case of user login the method login() has to be called and when the server responds the method onLoginResponse() is executed.
What I want to do is to bind actions with user interface. In the GUI class I created an instance of CommunicationManager called mCommunicationManager. From GUI class the login() method is simply called by the line
mCommunicationManager.login();
What I don't know how to do is binding the method from GUI class to onLoginResponse(). For example if the GUI class includes the method notifyUser() which displays the message received from theserver.
I would really appreciate if anyone could show how to bind methods in order to execute the method from GUI class (ex. GUI.notifyUser()) when the instance of the class mCommunicationManager receives the message from the server and the method CommunicationManager.onLoginResponse() is executed.
Thanks!
There's two patterns here I can see you using. One is the publish/subscribe or observer pattern mentioned by Pete. I think this is probably what you want, but seeing as the question mentions binding a method for later execution, I thought I should mention the Command pattern.
The Command pattern is basically a work-around for the fact that java does not treat methods (functions) as first class objects and it's thus impossible to pass them around. Instead, you create an interface that can be passed around and that encapsulates the necessary information about how to call the original method.
So for your example:
interface Command {
public void execute();
}
and you then pass in an instance of this command when you execute the login() function (untested, I always forget how to get anonymous classes right):
final GUI target = this;
command = new Command() {
#Override
public void execute() {
target.notifyUser();
}
};
mCommunicationManager.login(command);
And in the login() function (manager saves reference to command):
public void login() {
command.execute();
}
edit:
I should probably mention that, while this is the general explanation of how it works, in Java there is already some plumbing for this purpose, namely the ActionListener and related classes (actionPerformed() is basically the execute() in Command). These are mostly intended to be used with the AWT and/or Swing classes though, and thus have features specific to that use case.
The idiom used in Java to achieve callback behaviour is Listeners. Construct an interface with methods for the events you want, have a mechanism for registering listener object with the source of the events. When an event occurs, call the corresponding method on each registered listener. This is a common pattern for AWT and Swing events; for a randomly chosen example see FocusListener and the corresponding FocusEvent object.
Note that all the events in Java AWT and Swing inherit ultimately from EventObject, and the convention is to call the listener SomethingListener and the event SomethingEvent. Although you can get away with naming your code whatever you like, it's easier to maintain code which sticks with the conventions of the platform.
As far as I know Java does not support method binding or delegates like C# does.
You may have to implement this via Interfaces (e.g. like Command listener.).
Maybe this website will be helpful:
http://www.javaworld.com/javaworld/javatips/jw-javatip10.html
You can look at the swt-snippets (look at the listeners)
http://www.eclipse.org/swt/snippets/
or you use the runnable class , by overwritting the run method with your 'callback'-code when you create an instance
Related
I'm trying to get an understanding of which concrete types are providing the implementations of interfaces in an IOC (dependency injection) container. My implementation works fine when there are no delegates involved. However, I'm having trouble when a delegate method is passed as the type factory, as I can't get Mono.Cecil to give me the concrete type or a method reference to the factory back. I'm specifically in this case trying to build a component that can work with the IServiceCollection container for .Net ASP.Net REST APIs. I've created a 'minimised' set of code below to make it easy to explain the problem.
Consider the following C# code:
interface IServiceProvider {}
interface IServiceCollection {}
class ServicesCollection : IServiceCollection {}
interface IMongoDBContext {}
class MongoDBContext : IMongoDBContext
{
public MongoDBContext(string configName) {}
}
static class Extensions
{
public static IServiceCollection AddSingleton<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class
{
return null;
}
}
class Foo
{
void Bar()
{
IServiceCollection services = new ServicesCollection();
services.AddSingleton<IMongoDBContext>(s => new MongoDBContext("mongodbConfig"));
}
}
When successfully locating the 'services.AddSingleton' as a MethodReference, I'm unable to see any reference to the MongoDBContext class, or its constructor. When printing all the instructions .ToString() I also cannot seem to see anything in the IL - I do see the numbered parameter as !!0, but that doesn't help if I can't resolve it to a type or to the factory method.
Does anyone have any ideas on how to solve this?
Most likely your code is looking in the wrong place.
C# compiler will try to cache the conversion of lambda expression -> delegate.
if you look in sharplab.io you'll see that the compiler is emitting an inner class '<>c' inside your Foo class and in that class it emits the method '<Bar>b__0_0' that will be passed as the delegate (see opcode ldftn).
I don't think there's an easy, non fragile way to find that method.
That said, one option would be to:
Find the AddSingleton() method call
From there start going back to the previous instructions trying to identify which one is pushing the value consumed in 1 (the safest way to do that would be to consider how each instruction you are visiting changes the stack). In the code I've linked, it would be IL_0021 (a dup) of Bar() method.
From there, do something similar to 2, but now looking for the instruction that pushes the method reference (a ldftn) used by the ctor of Func<T, R>; in the code linked, it would be IL_0016.
Now you can inspect the body (in the code linked, Foo/'<>c'::'<Bar>b__0_0')
Note that this implementation has some holes though; for instance, if you call AddSingleton() with a variable/parameter/field as I've done (services.AddSingleton(_func);) you'll need to chase the initialization of that to find the referenced method.
Interestingly, at some point Cecil project did support flow analysis (https://github.com/mono/cecil-old/tree/master/flowanalysis).
If you have access to the source code, I think it would be easier to use Roslyn to analyze it (instead of analyzing the assembly).
For those of you that are familiar with the building of the Symfony container, do you know what is the differences (if any) between
Tagged service Collector using a Compiler pass
Tagged service Collector using the supported shortcut
Service Locator especially, one that collects services by tags
Specifically, I am wondering about whether these methods differ on making these collected services available sooner or later in the container build process. Also I am wondering about the ‘laziness’ of any of them.
It can certainly be confusing when trying to understand the differences. Keep in mind that the latter two approaches are fairly new. The documentation has not quite caught up. You might actually consider making a new project and doing some experimenting.
Approach 1 is basically an "old school" style. You have:
class MyCollector {
private $handlers = [];
public function addHandler(MyHandler $hamdler) {
$handlers[] = $handler;
# compiler pass
$myCollectorDefinition->addMethodCall('addHandler', [new Reference($handlerServiceId)]);
So basically the container will instantiate MyCollector then explicitly call addHandler for each handler service. In doing so, the handler services will be instantiated unless you do some proxy stuff. So no lazy creation.
The second approach provides a somewhat similar capability but uses an iterable object instead of a plain php array:
class MyCollection {
public function __construct(iterable $handlers)
# services.yaml
App\MyCollection:
arguments:
- !tagged_iterator my.handler
One nice thing about this approach is that the iterable actually ends up connecting to the container via closures and will only instantiate individual handlers when they are actually accessed. So lazy handler creation. Also, there are some variations on how you can specify the key.
I might point out that typically you auto-tag your individual handlers with:
# services.yaml
services:
_instanceof:
App\MyHandlerInterface:
tags: ['my.handler']
So no compiler pass needed.
The third approach is basically the same as the second except that handler services can be accessed individually by an index. This is useful when you need one out of all the possible services. And of course the service selected is only created when you ask for it.
class MyCollection {
public function __construct(ServiceLocator $locator) {
$this->locator = $locator;
}
public function doSomething($handlerKey) {
/** #var MyHandlerInterface $handler */
$handler = $serviceLocator->get($handlerKey);
# services.yaml
App\MyCollection:
arguments: [!tagged_locator { tag: 'app.handler', index_by: 'key' }]
I should point out that in all these cases, the code does not actually know the class of your handler service. Hence the var comment to keep the IDE happy.
There is another approach which I like in which you make your own ServiceLocator and then specify the type of object being located. No need for a var comment. Something like:
class MyHandlerLocator extends ServiceLocator
{
public function get($id) : MyHandlerInterface
{
return parent::get($id);
}
}
The only way I have been able to get this approach to work is a compiler pass. I won't post the code here as it is somewhat outside the scope of the question. But in exchange for a few lines of pass code you get a nice clean custom locator which can also pick up handlers from other bundles.
I'm starting from a functioning SignalR web application with an ActivityHub class derived from a SignalR Hub to manage client connections and activities. Similar to the stock ticker tutorial, there is also a singleton ActivityTimer class that uses a System.Threading.Timer to periodically broadcast to all clients via the hub context it gets in its constructor, like this:
activityHubContext = GlobalHost.ConnectionManager.GetHubContext<ActivityHub>();
Now I want to turn my ActivityHub into a base class with sub-classes for different kinds of activities, overriding a few methods in ActivityHub for activity-specific behaviors, and using activity-specific clients which each reference the appropriate activity sub-class (e.g., var activityHub = $.connection.coreActivityHub).
The sub-classing works for the hub server code and clients, and the ActivityTimer fires timer events as intended, but the ActivityTimer calls no longer reach the clients. If I get the hub context for a specific activity sub-class, it works again, but only for that sub-class:
activityHubContext = GlobalHost.ConnectionManager.GetHubContext<CoreActivityHub>();
Is there a way to have a single, generic ActivityTimer that will work with all sub-classes of ActivityHub? Can the ActivityTimer call some method in the base ActivityHub class rather than trying to reach all the clients directly (the base class seems to have no problems calling Clients.All.doSomething())?
In case it simplifies things (or makes possible an otherwise challenging solution), the application will only be running one type of activity at a time -- all clients will be on the same activity at one time.
In working on a different issue in the same project, I came across this, which points to this, where I also found this (all worth a quick read if the topic interests you). They provide one way to do what I was trying to do: have a method in the base class that can be called from "outside" to reach clients of any/all sub-classes. (They also helped me to think more clearly about the hub context, and why I believe my original ActivityTimer cannot work with sub-classes -- see note at the end of this answer for further explanation).
The solution to my problem is to create a method in the base class that does the call to the clients, and then call this new method from the ActivityTimer to reach the clients indirectly. This approach does not rely on having a hub context within ActivityTimer, and it frees us from worry about sub-classes because it calls into the base class explicitly:
Create a static field in the base class to hold the base class's hub context:
private static IHubContext thisHubContext;
Set this hub context in each sub-class's constructor with that class as the type passed to GetHubContext():
thisHubContext =
GlobalHost.ConnectionManager.GetHubContext<CoreActivityHub>();
Create a static method in the base class that calls the desired client-side method(s); note that you could use other options than Clients.All to reach a subset of clients (for example, the arg might designate a SignalR group to reach):
public static void DoSomething(string someArg)
{
thisHubContext.Clients.All.doSomething(someArg);
}
Call this base-class method from any server code that is "outside" the hub. In my case, I call it from the timer event handler in ActivityTimer:
ActivityHub.DoSomething("foo");
The messages will get through to the clients specified in the static method.
NB: this solution only works for the particular case mentioned at the end of the original post, in which only one sub-class is ever in use at a time, because each sub-class sets the base class static hub context to its own context. I have not yet tried to find a way around this limitation.
Note: I don't think it's possible to have "outside-the-hub" server code work with sub-classes by way of a stored hub context. In my original, functioning app (before I tried to create sub-classes of the ActivityHub), the ActivityTimer talks to the clients by means of a hub context that it gets on instantiation:
public ActivityTimer()
{
activityHubContext = GlobalHost.ConnectionManager.GetHubContext<ActivityHub>();
activityTimer = new Timer(DoSomething, null, TimerInterval, TimerInterval);
}
public void DoSomething(object state)
{
activityHubContext.Clients.All.doSomething("foo");
}
Because the hub context is obtained by explicit reference to a particular class (in this case, ActivityHub), it will not work with a sub-class. If instead (as I mentioned trying in my original post) I get the hub context for a particular sub-class, the timer will now work for instances of that sub-class, but not other sub-classes; again, the problem is that the hub context is obtained for a particular sub-class.
I don't think there's any way around this, so I think the only solution is the one outlined above in which the base class method uses the hub context set by the sub-class constructor, and the outside code calls the base class method to get to the clients by way of that sub-class context.
However, I'm still on the SignalR learning curve (among others) so will appreciate any corrections or clarifications!
In JavaFx, I understand that if I want a button to make some code run when it is clicked, I need to somehow have the code that I want to have run inside a method, and because this is Java, I wrap that method inside a class that extends EventHandler . For example:
// (myButton is a reference variable to a Button object)
myButton.setOnAction(new MyButtonEventHandlerClass() );
// inner class
public class MyButtonEventHandlerClass extends EventHandler<ActionEvent>{
public void handle(ActionEvent e) {
// (some code)
}
}
My confusion is: why is JavaFX designed to require me to make an instance of the class holding the handle() method? I had thought that non-static methods are used when the instance variables of an object are used; or in other words, if you just need a method that does not need an object, then you should use a static method. In this kind of thinking, handle() sounds like it should be a static method.
Why is handle() not a static method?
The criteria for a EventHandler to work in a meaningful way in this case are:
There needs to be some way to store the information.
The information has to be stored in a way that allows more than one way of dealing with a event.
Now regardless of the handle method actually using any fields in the EventHandlerand/or enclosing classes, there needs to be a way do identify the code that should handle the event.
If handle only was a static method, there only would ever be a single handler which even worse would be determined by the JavaFX programmers, since static methods cannot be overridden. It would not be possible to fulfil condition 2. without a non-static method.
For non-static methods however it's pretty simple to deal with this. Methods can be overridden and handling the event the correct way can simply be done by invoking EventHandler.handle for the event handler object.
In java 8 however method references (or lambda expressions) could be used to shorten this a bit by using method references, which allows you to "use a method as interface instance":
public class MyClass {
public static void handleMyButtonAction(ActionEvent evt) {
// (some code)
}
}
myButton.setOnAction(MyClass::handleMyButtonAction);
In my Flex 4.5 application I have a TitleWindow Settings.mxml, which is popped up by the PopUpManager.
Once the user has changed some settings, I not only need to save them to a SharedObject, but also to apply them to the main Application itself - so that the changes are visible to the user immediately.
For example I need to call its method hideApp(somevalue);
The spark.components.Application does not seem to have any static/singleton methods to get ahold of it.
So how do you do it?
And I also wonder how to declare, that an MXML file implements one or several interfaces?
package {
public interface Hiddable {
function hideApp(value:Number):void;
}
}
I'm asking this, because besides the main Application I have a SettingsTest.mxml Application in my project for "unit testing" that particular functionality.
Thank you! Alex
Yes it does:
FlexGlobals.topLevelApplication
though I would recommend you use events to avoid tight coupling.
As for the question about interfaces: use the attribute implements
<s:Component ... implements="IClassA,IClassB" ... />
About implementing of interfaces in MXML components see the following documentation.
What about passing changed data back from your pop up window to the application I recommend you to use Observer pattern with Flash event model something like the following:
var myWindow:MyWindow = MyWindow(PopUpManager.createPopUp(this, MyWindow));
myWindow.addEventListener(MyWindowEvent.SUBMIT, myWindowSubmit);
private function myWindow(event:MyWindowEvent):void
{
// Unsubscribing from events
var myWindow:MyWindow = MyWindow(event.currentTarget);
myWindow.removeEventListener(MyWindowEvent.SUBMIT, myWindowSubmit);
// Changed data is passing with custom event object
someData = event.someData;
}
And you should implement your custom event for that (MyWindowEvent in my pseudo code) and fire it from your TitleWindow component. You can read more about implementing custom event in documentation.