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

Pages: [1] 2
Print
Author Topic: .NET versions  (Read 33369 times)
JCabot
Courseware Beta
Jr. Member
***
Posts: 11


View Profile Email
« 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
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: January 10, 2008, 01:10:07 »

I think we should probably have solutions for both. I don't know if Matt is set up for .NET1.1, so you may have to collaborate with him to create these solutions and add them to the project.

Also, please keep me informed on your progress with PocketPC 2003. I have a Toshiba e755 which is essentially a brick right now, but I'd love to do something useful with it.

-=Cliff>
Logged
Gradiation
Port to CSharp
Full Member
*
Posts: 41


View Profile Email
« Reply #2 on: January 11, 2008, 01:45:50 »

Seeing as how all the source files are just links to a central folder, the way i saw it working was rather than creating seperate ports how as2 and as3 do, we should just need to create seperate solution files.

So maybe the PureMVC.DotNET solution needs changing to something like PureMVC.DotNET.vs2008.sln and we just create PureMVC.DotNET.vs2005.sln and PureMVC.DotNET.vs2003.sln. (I have vs2005 and vs2008 installed, so i may need you to create the PureMVC.DotNET.vs2003 solution file for me if you can)

The code itself should use very low level types / methods, and while all versions of the .NET framework support these, i think it's best to keep them as one port and just create these seperate solutions.

Thanks for the code change also, glad to see it wasn't too much of a struggle getting it working. I'll get that change tested and implemented tonight and recomit it. If you want to send me through your solution file, i'll get that commited aswell, and will also rename the solutions files as per this post.
« Last Edit: January 11, 2008, 01:52:19 by Gradiation » Logged
JCabot
Courseware Beta
Jr. Member
***
Posts: 11


View Profile Email
« Reply #3 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.
Logged
Gradiation
Port to CSharp
Full Member
*
Posts: 41


View Profile Email
« Reply #4 on: January 11, 2008, 12:51:29 »

Every demo helps.

I think it'll be good to have a mixture, some ports of existing demos, and some new ones to get others thinking.

So either/both would be fantastic.

Matt
Logged
Gradiation
Port to CSharp
Full Member
*
Posts: 41


View Profile Email
« Reply #5 on: January 11, 2008, 01:37:28 »

Hi J,

I have just tested the change you have asked for, and it makes the current tests fail.

The problem we have using C# is that it's hard to make an extendable singleton which is thread safe. I don't pretend to know a lot about this, but my implementation was based around this.

I'll have to try and look into this a bit more so can't comit it right now.

Can i ask what code is failing for you when the Facde is left in? as i managed to write the silverlight login demo no problem with it still in.

Matt

PS Don't suppose anybody has any ideas on how to implement an extenable thread safe singleton do they?
Logged
JCabot
Courseware Beta
Jr. Member
***
Posts: 11


View Profile Email
« Reply #6 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 :))
Logged
Gradiation
Port to CSharp
Full Member
*
Posts: 41


View Profile Email
« Reply #7 on: January 15, 2008, 01:55:57 »

Nice one,

I think the problem we have is that AS3 isn't a multithreaded environment so our port will always have to have a slight varitaions, and your solution, whilst it does add a little more code, it is still sticking to the origional as close as possible.

If this passes the unit tests, i myself would be happy with this solution as long as we just document the differences between our implementation.

If you want to add this to your version and send it through with the comments i'll get it murged in.

Good work Jason.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #8 on: January 15, 2008, 07:54:00 »

Hi guys,

I am not entirely sure this is necessary. Java is multithreaded but doesn't require this in a Singleton's getInstance.

And this makes the implementation of the Facade much more painful. Enough so that without middleware generating it, people will balk at it.(I would)

I'm not at the computer right now, but will try to see if I can figure out what you need soon from the java port.

-=Cliff> 
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #9 on: January 15, 2008, 07:59:30 »

J,

>> but casting it as an ApplicationFacade fails (because it's just a Facade) so getInstance returns null.<<

I don't get this. If instance is null a new ApplicationFacade is created. Not Facade. Can you explain?

-=Cliff>
Logged
JCabot
Courseware Beta
Jr. Member
***
Posts: 11


View Profile Email
« Reply #10 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...
Logged
Gradiation
Port to CSharp
Full Member
*
Posts: 41


View Profile Email
« Reply #11 on: January 15, 2008, 02:31:27 »

I did look around quite a bit when i was doing the conversion and struggled to find a decent solution (but then i don't pretend to know a lot about multithreading and being thread safe) so hopefully Jason can find something i didn't.

Cliff, wouldn't this just come under the idiosyncrasies that a port might require? I mean, the implementation offered by Jason at the moment, is the closest syntaticaly and functionaly that i'm aware of in C# to implement the singleton pattern in a safe manor that is consistant with the other ports.

I guess what i'm asking is, when it comes to trade offs, what should be sacrificed?
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #12 on: January 16, 2008, 08:37:59 »

Hi again guys.

Jason,

Thanks for the debugger step through. That's a great help.

From that I deduce that somehow simply referencing the instance var in an expression has caused c# to automagically initialize it.

Is the type of instance ApplicationFacade? Should be.Leaves the question why we end up with a Facade.

But, nevermind that. Let's take instance out of the expression.

Create a var called initialized of type boolean, initializing it to false in its declaration.

Then in the getInstance method, test the initilized boolean rather than testing the instance var itself.

Matt,

Trade offs have to fall on the side of ease of use and understandability. Of course each comes on its own terms. We certainly have to work this one to the very nth though because when the public starts hammering on 'why did you do it this way' you've got to have a defensable position that shows you exhausted all possibilities.

Of course it is open source so others will find better answers if they exist, but better to have found them first :)

-=Cliff>
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #13 on: January 16, 2008, 08:40:56 »

BTW, Jason: set initialized=true after creating the ApplicationFacade instance.

-=Cliff>

Logged
JCabot
Courseware Beta
Jr. Member
***
Posts: 11


View Profile Email
« Reply #14 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'
Logged
Pages: [1] 2
Print