2013-08-06 61 views
1

我为经常变化的软件创建了一个插件。我希望我的插件能够与主软件的每个新版本一起工作。这就是为什么我在通过反射创建插件的主对象之前,短时间加载插件的依赖关系(这是主软件的可执行文件)。C#反射:等待DLL完全加载,然后创建对象?

但是,这并不总是奏效:我有时间问题。 DLL有时不会被加载(完全),但是执行创建主对象的代码。这将导致缺少依赖关系的异常。

如何在创建对象之前等待DLL完全加载?

class PluginStarter 
    { 
     private MainPluginObject mainPluginObject = null; 

     public PluginStarter() 
     { 
      AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) => 
      { 
       var fullAssemblyName = new AssemblyName(eventArgs.Name);    

       if (fullAssemblyName.Name.Equals("MainSoftware")) 
       { 
        var found = Assembly.LoadFile(Path.Combine(Environment.CurrentDirectory, AppDomain.CurrentDomain.FriendlyName)); 
        return found; 
       } 
       else 
       { 
        return null; 
       } 
      }; 

      Initialize(); 
     } 

     private void Initialize() 
     { 
      mainPluginObject = new MainPluginObject(); 
     } 

     public void ShowForm() 
     { 
      mainPluginObject.ShowForm(); 
     } 

     public void Dispose() 
     { 
      mainPluginObject.Dispose(); 
     } 
    } 

只要我在衬里停用这个Initialize()[MethodImpl(MethodImplOptions.NoInlining)]它只是工作。 正在取消内部正确的解决方案吗? 如果在Assembly中没有事件通知您有关DLL加载状态,还能做些什么?

+0

您是否验证过要返回null的程序集? –

+0

@ LasseV.Karlsen:我想把'null'换成其他的东西。 –

+0

尝试'Assembly.LoadFrom'而不是'Assembly.LoadFile',看看它是否有任何区别。更多关于[this](http://stackoverflow.com/questions/1477843/difference-between-loadfile-and-loadfrom-with-net-assemblies)。 – Noseratio

回答

1

如果你的方法是在成荫,然后将需要的DLL,因此加载之前你PluginStarter调用构造函数(正在编译的方法时),特别是,这意味着你的AssemblyResolve事件已被初始化之前。

因此,要么您需要确保Initialize不是内联的,否则将您的AssemblyResolve代码放在静态构造函数中。

使用静态构造函数可能会更干净,因为它只会创建一个事件,无论创建多少个PluginStarter对象。