views:

731

answers:

2

This is the error I am getting in the handleModuleReady function:

[Fault] exception, information=TypeError: Error #1034: Type Coercion failed: 
can not convert MyModule@39b8479 to IModuleInterface.

I have an application setup and I have created modules to load at runtime in order to decrease the filesize (as most users will only ever need one of the modules).

<!-- maker.mxml -->
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
  xmlns="*"
  layout="absolute" 
  creationComplete="init(event)">
<mx:Style source="css/maker.css" />
<mx:Script>
<![CDATA[
 //Modules
 import mx.events.ModuleEvent;
 import mx.modules.ModuleLoader;
 import mx.modules.ModuleManager;
 import mx.modules.IModuleInfo;

 private var info:IModuleInfo;

 ...
    private function init(e:Event):void {
        info = ModuleManager.getModule("MyModule.swf");
        info.addEventListener("ready", handleModuleReady);
        info.addEventListener("error", handleModuleError);
        info.load(ApplicationDomain.currentDomain);
    }

    private function handleModuleReady(moduleEvent:ModuleEvent):void {
        var ichild:IModuleInterface = IModuleInterface(moduleEvent.target.factory.create());
        if (ichild != null) {
          //call class functions here via ichild object
        }
        else {
          trace("Something has gone wrong.");
        }
    }
...
</mx:Script>
...

I have created the IModuleInterface class (IModuleInterface.as), and the MyModule.mxml file compiles without issue, but I continue to get the typecasting error despite trying a variety of potential solutions such as loading the module through ModuleLoader, ModuleManager, and most recently setting the applicationDomain.

Please tell me if you know how to fix this. The rest of the internet doesn't. Trust me, I've looked.

If relevant, the interface looks something like this.

//IModuleInterface.as
package
  {
    public interface IModuleInterface {
    function getSomeClass():Class;
    function getSomeArray():Array;
    function getSomeInt():int;
  }
}
A: 

I have read the question wrong

Try this:

var module :IModuleInterface = evt.module.factory.create() as IModuleInterface;
ghalex
If the interface is defined in the parent application domain, an implementing class in a child domain can be cast to the interface. This is only not possible if a new application domain (not a child) is created.
Richard Szalay
Yes you are right, I have read the question wrong, it is a casting problem.
ghalex
+1  A: 

First, if you want to compare ichild to null, you should use as to do the cast:

var ichild:IModuleInterface = moduleEvent.target.factory.create() as IModuleInterface;

Secondly, can you confirm that create() is returning an instance of the module (and not something that wraps it)? From the looks of your error, it is.

Assuming it is, it's possible that your package-less interface could be the problem. Put it into a package, and make sure the same interface interface is referenced by both the main application and the module.

Let me know how that goes.

Richard Szalay
Thank you so much! Moving the interface into a package, updating the module and application code to reflect this, and recompiling did the trick.
calvinf