简体   繁体   中英

Instantiate an instance from a specified assembly that inherits from a base class - apparently very difficult problem

I have a class:

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;
    }
}

I have a number of classes that inherit from this class, that reside in various DLLs (including the one this is being called from, but in a different location). I need to be able to instantiate an instance of this class from the DLL location and class name. Currently I am using:

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;

But I keep getting the error:

Constructor on type 'TDXDataTypes.DotNet_WS_Components.InternationalAgencyFileOut' not found.

I'm sure my arguments match the constructor perfectly, and when loading the class from the same assembly using Activator.CreateInstance, it works fine:

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();

The particular example I'm working on at the moment is:

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

What does the constructor (or constructors) of TDXDataTypes.DotNet_WS_Components.InternationalAgencyFileOut look like? It almost sounds as if there is no contructor accepting the three arguments that you pass. Are they of the same types as the expected arguments in the constructor of the class?

Update

Regarding your second code sample; you have a rather different set of BindingFlags in the two examples. The failing one specifies BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly , while the working one uses only BindingFlags.CreateInstance . Could it be this difference that causes one to fail and one to succeed?

Since your bindingflags deviate in the two examples your giving and since getting them wrong will give you the stated exception Im guessing that's your problem.

UPDATE: If that's not the acse I'd compare the assembly versions

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

might not return the same version of the assembly (or even the same assembly) that the call to Activator is using so there's a potential risk that the type definition differs.

Try dumping the value of format.ClassName, assembly name/version/culture/key-hash (from the call to LoadFrom) and obj.GetType().AssemblyQualifiedName of the ISendAgencyFileComponent object you can create and compare

I managed to get this working with a simple workaround.

For any calls to the classes within the same assembly, I use the Activator.CreateInstance, and for any calls to a different DLL, I use the other method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM