2013-01-14 51 views
-1

我需要從包含一個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]價值版本之間切換編程?

+0

這不起作用,引用和使用x64庫的dl​​l無法同時加載或引用x86庫。你可以做的是創建一個接口項目(AnyCPU),然後通過反射裝載這些程序集,將其轉換爲接口並使用,就好像什麼也沒發生一樣。 – jessehouwing

+0

@jessehouwing:謝謝。你能否詳細說一下'interface project'。另外,如果我訴諸反思,是否有辦法讓Intellisense像早期綁定一樣工作? –

+0

是的,這是接口的整個想法:) – jessehouwing

回答

1

第1步:爲您在EmguCv中使用的對象創建接口,並將它們放置在單獨的AnyCpu項目中。如果這些對象沒有通用接口,或者無法更改這些對象,則需要爲這些類創建自己的包裝器對象。這些接口在自己的程序集中定義很重要,因爲您將從所有自己的代碼中引用該程序集。

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

現在,在現有的應用程序,使用反射或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接口,這會爲您提供強有力的結合,智能感知和所有您期望的其他內容,但是您將能夠根據您所處的上下文動態加載程序集。

如果您需要調用EmguCv對象上的非默認構造函數,那麼您可以使用Activator.CreateInstance(Type, Object[], Object[])重載或通過Type.GetConstructor(Type[]).Invoke()調用構造函數。

一旦您定義了接口,您也可以使用Unity或NInject等庫,以便您可以使用這些DI容器爲您完成反射工作。

相關問題