[Mono-list] Strange (Mono Only) problem with Assembly.CreateInstance?

daharper daharper at hotmail.com
Wed Dec 1 12:23:18 EST 2010


Hello All,

I've either being coding way past my bedtime, or something is not right with
either mono or my environment. 

I was hoping someone would be kind enough to confirm I'm doing the right
thing. 

In .NET land, everything is okay. This problem is only occurring in mono;
I'm using a parallel install of mono 2.8 on Ubuntu 10.10.

The code:

I have an interface, IGenerator, and inheriting from that I have an abstract
class Generator. 
I have three known Generators which inherit from Generator. 

I can create and invoke these just fine, and they do the job well:

private List<IGenerator> _generators;
...
Register<MySqlGenerator>(mdlGeneratorIds, "MySql");

Register<MsSqlGenerator2005>(mdlGeneratorIds, "SqlServer2005");

Register<MsSqlGenerator2008>(mdlGeneratorIds, "SqlServer2008");
...
foreach(var generator in _generators){

    while(generator.Execute(metadata));

}
...
private void Register<T>(string ids, string id) where T:IGenerator,new(){

      if(ids.Contains(id)){

          IGenerator generator=new T();

          Register(generator);

      }

}
...
void Register(IGenerator generator){              

    generator.OnFeedback+=_logger.Log;

    _generators.Add(generator);

}

I also have two other Generators which also inherit from Generator. The only
difference is the way that they are created (they are created from
information declared in an xml file):

private void Register(string id, Assembly assembly){

    IGenerator generator=(IGenerator)assembly.CreateInstance(id);

    Register(generator);

}

As mentioned, in .NET land everything works as expected.

My first problem in Mono was the CreateInstance was throwing a
TypeException:

Unhandled Exception: System.TypeLoadException: Could not load type
'BeaconDomainCppGenerator.Core.CppGenerator' from assembly
'BeaconDomainCppGenerator, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null'.

After some digging around, it turns out it didn't like the fact that
Generator was an abstract class. Not willing to argue with the compiler at
1am, I made the abstract method virtual. That solved the TypeException, the
correct class was being created, which was my CppGenerator.

However, when it executes, the overridden method is not called. 

For all intents and purposes it seems as if the runtime is treating the
object as a Generator rather than a CppGenerator. 

In Monodevelop, the debugger informs me that a CppGenerator was indeed
created, and I can confirm that "this" is in fact a CppGenerator as I'm
stepping through the code. 

Console.WriteLine(generator.GetType().Name) also confirms the type is a
CppGenerator.

And I can confirm that the initialization done in the CppGenerator has
happened.

This is the execute method in the Generator base class:

public bool Execute(CMetadata metadata){

    Metadata=metadata;

    return GenerateArtefacts();

}

This used to be the abstract method, but was made virtual in the Generator
base class:

protected virtual bool GenerateArtefacts(){ return false; }

And this is the declaration of the overriding method in the CppGenerator
class:

protected override bool GenerateArtefacts(){

As mentioned, the other classes created via new T() implement the virtual
method exactly the same and work as expected.

Using CreateInstance() to create the class, it failed when the base type
(Generator) was abstract, and it behaves as the base type when it executes. 

Any thoughts or have I entered the twilight zone?

Thanks in advance

David






-- 
View this message in context: http://mono.1490590.n4.nabble.com/Strange-Mono-Only-problem-with-Assembly-CreateInstance-tp3067714p3067714.html
Sent from the Mono - General mailing list archive at Nabble.com.


More information about the Mono-list mailing list