我有一程序集,用
Assmebly asm = Assembly.LoadFrom(..),
IProvider provider = (IProvider)asm.CreateInstance(..);这样转换,转换不了,
但是如果将代码移值到欲转换对象所在程序集的内部,然后用(IProvider)Assembly.GetExecutingAssembly().CreateInstance(..)这样就可以转换成功.
想了一天了,也没想出原因,大家帮帮忙吧..

解决方案 »

  1.   

    两个程序集内的IProvider必须相同。
      

  2.   

    LoadFrom(..)这个就是含有IProvider接口的程序集.并且LoadFrom(..)这个类同IProvider接口在同一个程序集中.
      

  3.   

    设写下Assembly.LoadFrom(..)的程序集为Main
    被LoadFrom的程序集为Project。那么,Main中的IProvider和Project中的IProvider只能有一个声明,这才能保证这两个IProvider是一样的。
    最好的解决方法是第三个程序集如Interface中定义IProvider接口,然后Main和Project均引用它,这个时候,两个程序集中的IProvider才是一样的。不然,就必须用反射来使用IProvider,这样编码太麻烦。
      

  4.   

    To: Ivony
    IProvider在Project中声明,而只是在Main中调用.

    namespace Project
    {
     public interface IProvider
     {
     }
     public class IOleProvider : IProvider
     {
     }
    }
    以上编译为Project.dll
    Main.cs
    {
     Assembly asm = Assembly.CreateInstance("Project.dll");
     IProvider provider = (Project.IProvider)asm.CreateInstance("Project.IOleProvider");
     //就是这样的,但就是不能转换.
    }
      

  5.   

    问题就出在你的Main.cs中的IProvider到底是什么?如果你的Main.dll中不存在IProvider的定义,那是语法错误,根本通不过编译。如果你的Main.dll中存在IProvider的定义,那么就算在Main.dll中定义的IProvider和在Project.dll中定义的IProject名称空间和方法签名都完全一模一样,.NET也会认为这是两个不同的接口,asm.CreateInstance("Project.IOleProvider")创建的是Project.IProvider接口的对象,而它肯定不符合Main.IProvider接口。解决方案其实也很简单,就像上面那样弄个接口程序集,或者令Project.dll引用Main.dll,使用Main.dll中定义的IProvider也行。
    另外就是,你的写法接口也能创建实例?
      

  6.   

    Main.dll中没有声明IProvider,IProvider只是在Project.dll中声明的那一个,IOleProvider是实现IProvider接口的类.
    Main.dll只是引用Project.dll中的IProvider接口
      

  7.   

    Main.dll中没有声明IProvider,IProvider只是在Project.dll中声明的那一个,IOleProvider是实现IProvider接口的类.
    Main.dll只是引用Project.dll中的IProvider接口
    那就奇怪了,既然是引用了,你还要动态加载干吗?
    类名不要以I开头,很容易被误会
      

  8.   

    因为那是一个动态创建IProvider,Project.dll中有几个分别实现了IProvider的类,CreateInstance(..)是根据不同的类来创建相应类的接口,整个操作都通过接口进行操作.
    当在Project.dll中用Assembly.GetExecuteAssembly().CreateInstance(..)可以创建实例并可以转换为IProvider,但是在外部或在Project.dll中用Assembly.LoadFrom(..).CreateInstance(..)时,却不能转换为IProvider.
      

  9.   

    还是不明白,如果你的Main引用了Project,就不用再Assembly.LoadFrom了哈,直接Assembly.GetAssembly( typeof( IProvider ) )不就行了?当然,你这个问题也确实奇怪。有空我试试。加载一个项目的时候,被引用的那些项目是一同被加载的啊。
      

  10.   

    对了,是没有引用,是通过CreateInstance(..)动态创建的.
      

  11.   

    Project.dll
    public interface IDataProvider
    {
    System.Data.IDbConnection GetConnection( string connString ); System.Data.IDbDataParameter IParameter( string name, BD_DbType dbType ); System.Data.IDbDataParameter IParameter( string name,BD_DbType dbType,int size, string srcColumn ); int ConverterBD_DbType( BD_DbType dbType );

    System.Data.IDbDataAdapter IDataAdapter
    {
    get;
    }
    }
    --------------------
    public class OleAccessProvider : BD.Data.IDataProvider
    {
    public OleAccessProvider(){}
    #region IDataProvider 成员 public IDbConnection GetConnection(string connString)
    {
    return new OleDbConnection( connString );
    } public IDbDataParameter IParameter(string name, BD_DbType dbType)
    {
    return new OleDbParameter( name,(OleDbType)this.ConverterBD_DbType( dbType ) );
    } IDbDataParameter IDataProvider.IParameter(string name, BD_DbType dbType, int size, string srcColumn)
    {
    return new OleDbParameter( name,(OleDbType)this.ConverterBD_DbType( dbType ),size,srcColumn );
    } public int ConverterBD_DbType(BD_DbType dbType)
    {...} public IDbDataAdapter IDataAdapter
    {
    get
    {
    return new OleDbDataAdapter();
    }
    } #endregion
    }
    ------------------
    Main.dll
    public class Test
    {
    private IDbConnection conn;
    private IDbCommand comm;
    private IDataProvider provider;
    private IDbDataAdapter adapter;
    public void T( string str )
    {
    Assembly asm = Assembly.LoadFrom( @"Project.dll" );
    // Type type = asm.GetType( "BD.Data.OleAccessProvider" );
    provider = (BD.Data.OleAccessProvider)asm.CreateInstance("BD.Data.OleAccessProvider");这句就出错.
    // provider = (IDataProvider)Assembly.GetExecutingAssembly().CreateInstance("BDQQ.Data.SqlProvider");这样就可以创建实例
    this.conn = provider.GetConnection( str );
    this.comm = conn.CreateCommand();
    this.adapter = provider.IDataAdapter;

    }
      

  12.   

    provider = (IDataProvider)Assembly.GetExecutingAssembly().CreateInstance("BDQQ.Data.SqlProvider");这样就可以创建实例,
    这种情况下是将此部分放在Project.dll中,
    在Main.cs中根本就不能创建,难道要在Main.cs中也应该有IDataProvider接口的定义?
      

  13.   

    还是不明白,写在Main.cs中的IDataProvider是怎么来的,你又说你没引用Project,那这个IDataProvider怎么就平白无故的冒出来了?
    两种方案。总而言之,如果要利用IDataProvidor来进行两个程序集之间的调用,就必须让两个程序集都包含同一个IDataProvider的定义。
    可以在Main中定义,而Project引用Main,然后再利用在Main中定义的IDataProvider来实现n个类,这样,Main就可以动态加载Project,并利用自己的IDataProvider来执行操作。也可以在一个接口程序集中定义IDataProvider接口,而Main和Project都引用这个接口程序集。
      

  14.   

    终于明白了,原来是Main中没有对于IProvider的定义,将IProvider放到一个程序集中,然后在实现其的程序集中引用,再在Main.cs中引用,这样就应该可以了.
    谢谢Ivony()