none
Loading Assembly using Assembly.LoadFile() and type cast error RRS feed

  • Question

  • Hi,

    I need to get an assembly from a outside location of the current running assembly and create an object dynamically using the following way according to the name (nomeClasseCompleto) of class parameter. So when i receive the object it can not cast(Error: Specified cast is not valid) if i use Assembly.LoadFile() method


    ContiCorrenti obj = (ContiCorrenti)BOFactory.GetObject(ContiCorrenti");
    ****************************BOFactory*********************************************
      • public static Object GetObject(string nomeClasseCompleto)
      • {
      • //Assembly asm = Assembly.GetExecutingAssembly();
      • string pathBO = "D:\\projects\\BusinessObjects\\bin\\Debug\\BusinessObjects.dll";
      • Assembly asm = Assembly.LoadFile(pathBO);
      • Object o = null;
      • foreach (Type type in asm.GetTypes()) // for each type Class, Form
      • {
      • if (type.IsClass && type.Namespace.ToString() + "." + type.Name.ToString() == nomeClasseCompleto )
      • {
      • PropertyInfo[] properties = type.GetProperties();
      • o = Activator.CreateInstance( type );
      • }
      • }
      • return o;
      • }

    *******************************************************************

    but if i use
    //Assembly asm = Assembly.GetExecutingAssembly();


    from the current running assembly then it works fine.

    So far i understood, LodeFile method load the assembly from the file with some limitation.

    do you have any idea to solve this problem?


    Ferdous
    Thursday, March 5, 2009 11:47 AM

Answers

  •  Your code with fail when you add another assembly to the GAC.  Browsing the GAC is strictly forbidden.
    Hans Passant.
    • Marked as answer by MJ Ferdous Thursday, March 5, 2009 9:03 PM
    Thursday, March 5, 2009 6:25 PM
    Moderator
  • Yes, you cannot cast because the fully qualified type name of the type is different.  It is a type in BusinessObjects.dll, the only way to cast to that type is to add a reference to BusinessObject.dll.  Which defeats the purpose of using Assembly.LoadXxx().  You'll have to create a 3rd assembly that defines an interface.  ContiCorrenti should add a reference to that assembly and implement the interface.  Your main project should add a reference as well.  Now you can cast the return value of CreateInstance() to that interface.
    Hans Passant.
    • Marked as answer by MJ Ferdous Thursday, March 5, 2009 5:30 PM
    Thursday, March 5, 2009 1:19 PM
    Moderator
  • Yes if you are right may be when you read from bin directory from another project. i have been tried to add reference BusinessObject.dll and call Load method and it works fine in my above example.

    Assembly asm = Assembly.Load("BusinessObject");

    But i am not interested to put reference and i found the solution by loading from the GAC and it can cast properly without any problem see the following code.


    1. string pathBO = FindDllInGAC( "BusinessObjects" );
    2. Assembly asm = Assembly.LoadFile( sDll );

      **************************************************************
    3. private static string FindDllInGAC(string sRule)
    4. {
    5. string[] dirs = Directory.GetDirectories(Environment.ExpandEnvironmentVariables(@"%WINDIR%\assembly\GAC"),sRule);
    6. if (dirs.Length !=0)
    7. {
    8. string s = dirs[dirs.Length - 1];
    9. dirs = Directory.GetDirectories(s,"*");
    10. return dirs[dirs.Length - 1] + @"\" + sRule + ".dll";
    11. }
    12. return "";
    13. }



    ************************************************************

     

    Many Many thanks for your help


    Ferdous
    • Marked as answer by MJ Ferdous Thursday, March 5, 2009 5:30 PM
    Thursday, March 5, 2009 5:30 PM

All replies

  • I also used LoadFrom according to the following blog suggession but doesnt work.

    http://blogs.msdn.com/suzcook/archive/2003/09/19/57248.aspx
    Ferdous
    Thursday, March 5, 2009 11:59 AM
  • Yes, you cannot cast because the fully qualified type name of the type is different.  It is a type in BusinessObjects.dll, the only way to cast to that type is to add a reference to BusinessObject.dll.  Which defeats the purpose of using Assembly.LoadXxx().  You'll have to create a 3rd assembly that defines an interface.  ContiCorrenti should add a reference to that assembly and implement the interface.  Your main project should add a reference as well.  Now you can cast the return value of CreateInstance() to that interface.
    Hans Passant.
    • Marked as answer by MJ Ferdous Thursday, March 5, 2009 5:30 PM
    Thursday, March 5, 2009 1:19 PM
    Moderator
  • Yes if you are right may be when you read from bin directory from another project. i have been tried to add reference BusinessObject.dll and call Load method and it works fine in my above example.

    Assembly asm = Assembly.Load("BusinessObject");

    But i am not interested to put reference and i found the solution by loading from the GAC and it can cast properly without any problem see the following code.


    1. string pathBO = FindDllInGAC( "BusinessObjects" );
    2. Assembly asm = Assembly.LoadFile( sDll );

      **************************************************************
    3. private static string FindDllInGAC(string sRule)
    4. {
    5. string[] dirs = Directory.GetDirectories(Environment.ExpandEnvironmentVariables(@"%WINDIR%\assembly\GAC"),sRule);
    6. if (dirs.Length !=0)
    7. {
    8. string s = dirs[dirs.Length - 1];
    9. dirs = Directory.GetDirectories(s,"*");
    10. return dirs[dirs.Length - 1] + @"\" + sRule + ".dll";
    11. }
    12. return "";
    13. }



    ************************************************************

     

    Many Many thanks for your help


    Ferdous
    • Marked as answer by MJ Ferdous Thursday, March 5, 2009 5:30 PM
    Thursday, March 5, 2009 5:30 PM
  • This is grossly wrong.
    Hans Passant.
    Thursday, March 5, 2009 5:39 PM
    Moderator
  • Can you explain why?
    Ferdous
    Thursday, March 5, 2009 5:47 PM
  •  Your code with fail when you add another assembly to the GAC.  Browsing the GAC is strictly forbidden.
    Hans Passant.
    • Marked as answer by MJ Ferdous Thursday, March 5, 2009 9:03 PM
    Thursday, March 5, 2009 6:25 PM
    Moderator
  • Thanks. i must think about that.
    Ferdous
    Thursday, March 5, 2009 9:01 PM
  • OKay understood if there is two version then the code will fail
    but if i keep the version strict (i.e. 1.0.0.) then what happen?
    I think is should work fine or not.
    Let me know please.

    Note:We can not add as reference the dll bcoz there well be cross reference with the current DLL.
    Ferdous
    Friday, March 6, 2009 4:47 PM