Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Show Posts

* | |

  Show Posts
Pages: [1]
1  Announcements and General Discussion / Architecture / Re: RPC calls handling reponses and IOC on: March 07, 2008, 04:10:53
Another idea, instead of using the AsyncToken and custom responders in the mediators, is to use some kind of shared data between the mediators and proxy, then test on this when a notification is received (an example is probably the best way to describe what I mean)

:
Mediator:
protected var key:String = "someKeyForThisMediator";
protected function onKeyPress(event:Event):void
{
proxy.doSomething(key);
}
override public function handleNotification(notification:INotification):void
{
switch (notification.getName()) {
case ApplicationFacade.DO_SOMETHING_RESULT:
if (notification.getType() == key) updateView(notification.getBody());
break;
}
}

Proxy:
protected function doSomething(key=null):void
{
service.addEventListener(ResultEvent.RESULT, onDoSomethingResult)

var token:AsyncToken = service.send();
token.key = key;
}
protected function onDoSomethingResult(event:ResultEvent):void
{
var key:String = event.token.key;
sendNotification(ApplicationFacade.DO_SOMETHING_RESULT, event.result, key);
}

The advantage of doing it like this means that the mediator doesn't need to know that the proxy is calling a service, it just needs to know that it only updates the view when it receives a certain key in handleNotification.
2  Announcements and General Discussion / Architecture / Re: destroy/cleanup mediator before removal on: February 15, 2008, 11:36:59
I just thought I would let you know a way that I have implemented a dispose/destroy method just to get your thoughts on it. It means you don't have to keep casting things to their concrete mediator in order to call destroy on them, instead just use the IDisposable interface.

Have a public interface for disposable objects
:
public interface IDisposable
{
function dispose():void;
}

Implement this in your mediators/whereevers
:
public class MyMediator extends Mediator implements IMediator, IDisposable
{
...
public function dispose():void
{
viewComponent.removeEventListener(Event, function);
...
}
...
}


Register a command responsible for disposing objects
:
public class RemoveAndDisposeCommand extends SimpleCommand implements ICommand
{
override public function execute(notification:INotification):void
{
var mediatorName:String = notification.getBody() as String;
var toDestroy:IDisposable = facade.removeMediator(mediatorName) as IDisposable;

if (toDestroy != null) toDestroy.dispose();
}
}

Then if you want to remove a mediator from the system, you can simply write:
:
sendNotification(ApplicationFacade.REMOVE_AND_DISPOSE, mediatorName);
or whatever name you registered the command with

of course, this only works when removeMediator returns a reference to the mediator that was removed...
3  PureMVC Manifold / Standard Version / Re: .NET versions on: January 18, 2008, 04:12:07
Cool, yeah, just change the name to DotNETCF. I made it v5 originally only because I wasn't sure what else to call it! :)

Also, this isn't a demo yet, it's just the framework and test files, it's just I came across a few issues while trying to write a demo, I'll make another post when I get that sorted...
4  PureMVC Manifold / Standard Version / Re: .NET versions on: January 17, 2008, 05:00:25
The code in the facade can be changed to that style too :) less confusing that way and it still passes all tests on standard and compact framework. (this is what I've done, I've also changed the comments to match) see the attached file!
5  PureMVC Manifold / Standard Version / Startup idiom on: January 16, 2008, 09:53:20
What's the recommended way of performing startup in a windows application? The way I have been playing around with it, I have the following classes:

:
    class ApplicationRunner
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [MTAThread]
        static void Main()
        {
            IFacade facade = ApplicationFacade.getInstance();
            facade.startup(new Form1());
        }
    }

    class ApplicationFacade : Facade, IFacade
    {
        ...
        public override void startup(object app)
        {
            notifyObservers(ApplicationFacade.APP_STARTUP, app);
            Application.Run(app as Form);
        }
    }

just wondered what other peoples opinions are? Is there really a need to have an ApplicationRunner class? or just put the main method in the ApplicationFacade? Where do you recommend putting Application.Run (the built in .NET thing) in the facade or startup command? What are the Java guys doing?

[Edit: oops forgot some parts]
6  PureMVC Manifold / Standard Version / Re: .NET versions on: January 16, 2008, 09:49:01
using the initialized flag works, but doing it that way means you have to add the code back in to perform the lock on the shared object (so that multiple threads can't each create their own singleton)

I think I've found a nicer solution. When you implement your own Facade, how about having to write:

:
1        private ApplicationFacade() {}
2
3        static ApplicationFacade()
4        {
5            instance = new ApplicationFacade();
6        }
7
8        public static new ApplicationFacade getInstance()
9        {
10           return instance as ApplicationFacade;
11       }

This requires no changes in the c# framework code at the moment, just in the way the classes are implemented and in my opinion it is a lot more elegant than using locks.

Line 1 we don't have to do this, but otherwise people can just say ApplicationFacade app = new ApplicationFacade();

Line 8 has the new keyword to just tell the compiler that we do in fact mean to override getInstance() from Facade (it's not required, but stops a warning from being produced).

So technically you can write even less code (and more like the as3 version), without the private/protected constructor or the new keyword on getInstance, but doing it the way above would be 'best practice'
7  PureMVC Manifold / Standard Version / Re: .NET versions on: January 15, 2008, 08:48:23
Exactly, that's why I wasn't too sure about it either, I'm still trying to find a nicer and more elegant solution.

As Matt pointed out before, the problem is that it is quite hard to implement a thread-safe singleton that can be extended. In Java you can get away with doing:

:
public class Singleton {
   private final static Singleton INSTANCE = new Singleton();
 
   // Private constructor suppresses generation of a (public) default constructor
   private Singleton() {}
 
   public static Singleton getInstance() {
     return INSTANCE;
   }
 }
http://en.wikipedia.org/wiki/Singleton_pattern#Traditional_simple_way

Using the same method in C# I run into the problem where in ApplicationFacade (that extends Facade) testing "instance == null" has the side effect of instantiating instance as a Facade, so the test returns false and we never even reach the code that says instance = new ApplicationFacade

:
1        public static ApplicationFacade getInstance()
2        {
3            if (instance == null)
4            {
5                instance = new ApplicationFacade();
6            }
7            return instance as ApplicationFacade;
8        }

Put a breakpoint on line 3, check the value of instance, it is definitely null. Now using normal logic, it SHOULD go through to line 5 and create instance to be an ApplicationFacade, but instead it goes straight to line 7 with instance initialised as a Facade, so then "instance as ApplicationFacade" returns null because the cast fails.

Anyway, as I said, I'm still investigating it because I'm sure there must be a more elegant solution and I'm doing something a bit daft...
8  PureMVC Manifold / Standard Version / Re: .NET versions on: January 14, 2008, 01:16:49
In my ApplicationFacade, which extends Facade and implements IFacade:

:
        public static ApplicationFacade getInstance()
        {
            if (instance == null) instance = new ApplicationFacade();
            return instance as ApplicationFacade;
        }

The first time it is called with ApplicationFacade.getInstance(), it tests if (instance == null), but actually in this test, it initialises it to be a Facade, then the test for if (instance == null) returns false, but casting it as an ApplicationFacade fails (because it's just a Facade) so getInstance returns null. It took me a while to work out what was going wrong to be honest because it seems such a silly thing.

I'm guessing that this is something that changed with .NET 2.0+ but I haven't tested it with any other .NET 1.1 apps yet

As for a fix which passes the tests, this is how I've always created thread-safe singletons in the past, it's slightly less efficient probably because it acquires a lock everytime you call getInstance, but I'm not sure how important that really is in the grand scheme of things :)

:
In org.puremvc.csharp.patterns.facade.Facade.cs

        /// <summary>
        /// A simple object that can be shared between threads as a locking mechanism
        /// </summary>
        protected static object _sharedObject = new object();

        /// <summary>
        /// Facade Singleton Factory method
        /// </summary>
        /// <returns>The Singleton instance of the Facade</returns>
public static IFacade getInstance()
        {
            lock (_sharedObject)
            {
                if (instance == null) instance = new Facade();
            }
            return instance;
}

....
        /// <summary>
        /// The Singleton Facade Instance
        /// </summary>
        protected static IFacade instance;

Then in derived classes, you need to do

:
        public static ApplicationFacade getInstance()
        {
            lock (_sharedObject)
            {
                if (instance == null) instance = new ApplicationFacade();
            }
            return instance as ApplicationFacade;
        }

On the downside, it does add more code that you need to write everytime you implement an ApplicationFacade and it adds something that differs from the original framework, so what's everyones opinions on it?

(by the way, I've commented it all up with the XML comments now, depending on what we decide to do for this problem, I'll send you the files :))
9  PureMVC Manifold / Standard Version / Re: .NET versions on: January 11, 2008, 09:53:12
Aha, that sounds like a much better idea to use different solutions actually since they all use the same source code, I see why it's set up like that now :)

I only have Visual Studio 2005 and Visual Studio 2008 as well (so no 2003) but in 2005 you can still make .net 1.0 apps.

I'll email you with the solution tomorrow, I still just need to tidy it up (since I was really only testing if it worked ok before) :D

As for the Toshiba e755 being essentially a brick, I know the feeling, I have an ipaq 1940 and for some reason it isn't even recognised in vista!

And for a demo for the CF, I think just the standard Architecture 101 would make a good example, thoughts? As soon as I have some time again, I need to remake an old word game I had lying around, that might be quite interesting too.
10  PureMVC Manifold / Standard Version / XML Comments on: January 10, 2008, 12:44:41
I don't mind updating the comments above the methods and classes to be formatted as XML, let me know if this needs to be done and if you want a hand doing it.
11  PureMVC Manifold / Standard Version / .NET versions on: January 10, 2008, 12:37:27
Hiya,

Currently the solution is built with VS.NET 2008 which for some reason doesn't support .NET 1.1. Since none of the .NET 2.0+ specific features are being used, is it worth changing the project to build with VS 2005 and target .NET 1.1 or does Silverlight or something rely on .NET 2.0? (I still haven't looked into anything related with Silverlight yet)

I mainly ask because for the compact framework I really wanted it to target PocketPC 2003 which uses .net 1.1. Do you think we should maybe have different projects for different versions? similar to org.puremvc.as3 / org.puremvc.as2 or do you think that just makes it more complicated than it needs to be?

Anyway, I've got it working fine with the compact framework and .NET 1.1 by changing just one line.

:
org.puremvc.csharp.patterns.facade.facade.cs, line 368

protected static IFacade instance = new Facade();

to

:
org.puremvc.csharp.patterns.facade.facade.cs, line 368

protected static IFacade instance;

Otherwise getInstance always seems to return a Facade, rather than whatever extends it.

I didn't try committing this change because I wasn't sure the exact procedure that was being followed, so posting here seemed to be the safest bet  ;D
Pages: [1]