在多个版本的引用程序集之间自动切换

时间:2013-01-14 13:06:12

标签: .net reflection reference emgucv early-binding

我需要从包含一个C#WinForms项目的解决方案中引用EmguCV。

同一个库有四个版本,即x86 vand x64,每个版本都支持和不支持GPU。该库需要引用EmguCV的托管DLL以及OpenCV的非托管DLL。通过构建后事件,可以很容易地将正确的非托管版本复制到[Bin]文件夹。

我希望能够通过代码轻松切换托管引用。可能类似于以下内容:

public enum EnumEmguCvTarget
{
    None, // Do not use EmguCv
    EmguCvTargetTbb86, // Target EmguCv for x86 without GPU.
    EmguCvTargetGpu86, // Target EmguCv for x86 with GPU.
    EmguCvTargetTbb64, // Target EmguCv for x64 without GPU.
    EmguCvTargetGpu64, // Target EmguCv for x64 with GPU.
}

public EnumEmguCvTarget EmguCvTarget
{ get { return (EnumEmguCvTarget.EmguCvTargetGpu64); } }

由于我在编译时引用这些程序集(不是后期绑定),有没有办法可以根据[EmguCvTarget]的值以编程方式在版本之间切换?

1 个答案:

答案 0 :(得分:1)

步骤1:为EmguCv中正在使用的对象创建界面,并将它们放在单独的AnyCpu项目中。如果这些对象没有公共接口,或者当您无法更改这些对象时,则需要为这些类创建自己的包装器对象。这些接口在它们自己的程序集中定义非常重要,因为您将从所有自己的代码中引用此程序集。

 public interface IEmguCv{ /* methods and proeprties */ }
 public class EmguCv : IEmguCv { }

现在在您现有的应用程序中,使用Reflection或Activator.CreateInstance加载正确的程序集:

 // which assembly to load depends on your configuration
 Assembly emguAssembly = Assembly.Load("EmguX64");
 Type emguType = emguAssembly.GetType("EmguCvClassYouAddedInterfacesTo");
 IEmguCv object = (IEmguCv)Activator.CreateInstance(emguType);

从这里您可以使用IEmguCv接口,它将为您提供强大的绑定,IntelliSense以及您期望的所有其他功能,但您将能够根据您所处的上下文动态加载程序集。

如果你需要在EmguCv对象上调用非默认构造函数,那么你可以使用Activator.CreateInstance(Type, Object[], Object[])重载,或者通过Type.GetConstructor(Type[]).Invoke()调用构造函数。

一旦定义了界面,您也可以使用Unity或NInject等库,这样您就可以使用这些DI容器为您进行反射工作。