2009-07-22 8 views
1

J'ai une classe:instancier une instance d'un assembly spécifié qui hérite d'une classe de base - apparemment problème très difficile

public abstract class SendAgencyFileComponent : ISendAgencyFileComponent 
{ 
    public AgencyOutput agencyOutput; 
    public TDXDataTypes.DB.Entity client; 
    public TDXDataTypes.DB.Entity agency; 

    public SendAgencyFileComponent(AgencyOutput agencyOutput, TDXDataTypes.DB.Entity client, TDXDataTypes.DB.Entity agency) 
    { 
     this.agencyOutput = agencyOutput; 
     this.client = client; 
     this.agency = agency; 
    } 
} 

J'ai un certain nombre de classes qui héritent de cette classe, qui résident dans diverses DLL (y compris celui auquel on appelle, mais dans un endroit différent). J'ai besoin d'être capable d'instancier une instance de cette classe à partir de l'emplacement de la DLL et du nom de la classe. Actuellement, je suis en utilisant:

System.Reflection.Assembly assembly = 
    System.Reflection.Assembly.LoadFrom(
    "C:\\Program Files\\RMIS\\" + format.AssemblyName + ".dll"); 

return assembly.CreateInstance(
    format.ClassName, 
    true, 
    System.Reflection.BindingFlags.CreateInstance, 
    null, 
    new Object[] { agencyOutput, client, agency }, 
    System.Globalization.CultureInfo.CurrentCulture, 
    null 
    ) as DotNet_WS_Components.ISendAgencyFileComponent; 

Mais je continue à obtenir l'erreur:

Constructeur du type 'TDXDataTypes.DotNet_WS_Components.InternationalAgencyFileOut' not found.

Je suis sûr que mes arguments correspondent au constructeur parfaitement, et lors du chargement de la classe du même ensemble en utilisant Activator.CreateInstance, il fonctionne très bien:

System.Runtime.Remoting.ObjectHandle sendFilehandle = 
    Activator.CreateInstance(
     format.AssemblyName, 
     format.ClassName, 
     true, 
     System.Reflection.BindingFlags.CreateInstance, 
     null, 
     new Object[] { agencyOutput, client, agency }, 
     System.Globalization.CultureInfo.CurrentCulture, 
     null, 
     null); 

     return (TDXDataTypes.DotNet_WS_Components.ISendAgencyFileComponent)sendFilehandle.Unwrap(); 

L'exemple particulier, je travaille sur le moment est:

 
Webservice 
-> calls TDXDataTypes dll method through referenced DLL 
-> calls TDXDataTypes dll class (above) using reflection from a different folder 
+0

J'ai mis à jour ma réponse. –

Répondre

0

J'ai réussi à obtenir ce travail avec une solution de contournement simple.

Pour tous les appels aux classes au sein du même assembly, j'utilise Activator.CreateInstance, et pour tous les appels à une DLL différente, j'utilise l'autre méthode.

0

Qu'est-ce que le constructeur (ou constructeurs) de TDXDataTypes.DotNet_WS_Components.InternationalAgencyFileOut ressembler? On dirait presque qu'il n'y a pas de constructeur qui accepte les trois arguments que vous avez reçus. Sont-ils du même type que les arguments attendus dans le constructeur de la classe?

Mise à jour

En ce qui concerne votre deuxième exemple de code; vous avez un ensemble de BindingFlags plutôt différent dans les deux exemples. Celui qui échoue spécifie BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, tandis que celui qui fonctionne utilise seulement BindingFlags.CreateInstance. Se pourrait-il que cette différence fasse échouer et réussir?

+0

Le constructeur est exactement le même que celui de SendAgencyFileComponent – cjk

+0

Je devinerais la même chose. Vous devriez vérifier l'assemblage et le nom et vous assurer que vous êtes sûr de ce que vous attendez. –

+0

@David - cela fonctionne très bien en utilisant Activator.CreateInstance en utilisant presque exactement les mêmes paramètres de méthode (je vais ajouter cet exemple à la question), donc je suis sûr que c'est quelque chose à voir avec la DLL distante. – cjk

0

Étant donné que vos drapeaux de reliure dévient dans les deux exemples que vous donnez et que vous vous trompez, vous obtiendrez l'exception indiquée. Je suppose que c'est votre problème.

MISE À JOUR: Si ce n'est pas ACSE je compare les versions de montage

System.Reflection.Assembly assembly = 
    System.Reflection.Assembly.LoadFrom(
    "C:\\Program Files\\RMIS\\" + format.AssemblyName + ".dll"); 

pourrait ne pas retourner la même version de l'ensemble (ou même le même ensemble) que l'appel à Activator utilise donc il y a un risque potentiel que la définition de type diffère.

la valeur du dumping Essayez de format.ClassName, nom montage/version/culture/hachage clé (de l'appel à LoadFrom) et obj.GetType(). AssemblyQualifiedName de l'objet ISendAgencyFileComponent vous pouvez créer et comparer

+0

J'ai essayé beaucoup de comniations de drapeaux de liaison, y compris avoir le même sur les deux appels avec une version fonctionnant et l'autre ne fonctionne pas . – cjk

+0

La version d'assemblage * pourrait être le problème, mais je me souviens d'avoir déployé la même version sur les deux sites pour voir si cela fonctionnait. J'ai une solution de contournement maintenant, mais merci pour votre aide. – cjk

Questions connexes