2013-05-02 168 views
1

我正在嘗試編寫一個小型的c#/ .net庫來進行非常具體的財務計算。如何以編程方式檢查c#中是否存在程序集引用?

我寫了幾個只依賴於.net框架的標準程序集的類。也就是說,具有這些類的庫只需要.net框架(4.0客戶端)。

現在我需要一個額外的類來進行excel集成。該類將需要與Microsoft Office和Excel相關的其他裝配參考,如其各自的對象庫。

我的問題是:這個庫的一些用戶可能有office和excel,有些沒有。

如何將這個附加類添加到庫中,以便這兩種類型的用戶都可以使用該庫而不會出現錯誤?

更確切地說:如果用戶沒有office和excel,用戶必須能夠運行除excel相關的一個以外的所有類而不會出錯。

感謝您的幫助,selmar

回答

2

這應該工作開箱。組件按需加載,即在需要時加載它們。只要沒有使用Excel的用戶不使用Excel相關的類,就不會有錯誤。

+0

如何在代碼的頂部使用引用? using Excel = Microsoft.Office.Interop.Excel; 它不會導致在他的電腦上沒有office和excel的用戶的程序集引用錯誤嗎? – selmar 2013-05-02 17:14:03

+1

@selmar:裝配僅在使用時才加載。 「使用」是不夠的。實際上您需要枚舉或實例化程序集中的類型。 – 2013-05-02 18:11:46

0

你試過ILMerge?這將使您可以將所需的dll添加到您的可執行文件,以確保用戶具有所需的程序集

+0

好主意,但分發像微軟對象庫這樣的DLL是否合法? – selmar 2013-05-05 22:33:25

+0

我想是的,這是建立微軟,頁面上沒有任何內容說相反。 – 2013-05-06 07:16:40

3

我實際上正在做這樣的事情。大會被探查,如果他們存在/將工作。

您可以在許多方面,當然,做到這一點,但是這就是我結束了:

  • 提取這個類到接口的所有功能(我們稱之爲:IExcel),並加入IsAvailable屬性,它
  • 實現了實現IExcel的僞類,並從IsAvailable返回'false'(當然還有從其他方法拋出NotSupportedException)。
  • 創建新的組件(重要:新的裝配)與真正的實現IExcel的
  • 實現工廠類具有「創建」,這將決定哪一個應當返還和決心(或測試)

捕獲異常大會:MyFacade

// the interface 
public interface IExcel 
{ 
    bool IsAvailable { get; } 
    // your stuff 
} 

// the fake implementation 
public class FakeExcel: IExcel 
{ 
    public IsAvailable { get { return false; } } 
    // your stuff should probalby throw NotSupportedException 
} 

大會:MyImplementation

// real implementation 
public class RealExcel: IExcel 
{ 
    private bool? _isAvailable; 

    public bool IsAvailable 
    { 
     // return value if it is already known, or perform quick test 
     get { return (_isAvailable = _isAvailable ?? PerformQuickTest()); } 
    } 

    private bool PerformQuickTest() 
    { 
     try 
     { 
      // ... do someting what requires Excel 
      // it will just crash when it cannot be found/doesn't work 
     } 
     catch // (Exception e) 
     { 
      return false; 
     } 
     return true; 
    } 
} 

Assembly:MyFacadeFactory

public class ExcelFactory 
{ 
    public static IExcel Create() 
    { 
     // delay resolving assembly by hiding creation in another method 
     return Try(NewRealExcel) ?? new FakeExcel(); 
    } 

    private static IExcel Try(Func<IExcel> generator) 
    { 
     try 
     { 
      var result = generator(); 
      if (result.IsAvailable) 
       return result; 
     } 
     catch // (Exception e) 
     { 
      // not interested 
     } 
     return null; // didn't work exception or IsAvailable returned 'false' 
    } 

    // this could be implemented as delegate but it's 
    // safer when we put NoInlining on it 
    [MethodImpl(MethodImplOptions.NoInlining)] 
    private static IExcel NewRealExcel() 
    { 
     return new RealExcel(); 
    } 
} 

會發生什麼?

  • 如果您有Excel和MyImplementation組件可以被發現,就會被加載,RealExcel類將被創建,然後使用
  • 如果你沒有Excel,但你確實有MyImplementation組件,這將是將會創建RealExcel類,但會在'PerformQuickTest'上失敗,所以將使用FakeExcel
  • 如果MyImplementation程序集找不到(您沒有包含它),則在MyFacade中創建RealExcel時將失敗,因此FakeExcel將會已使用

您可以對照用動態加載和反射來完成所有這些事情(少量代碼行),但使用起來有點笨重。我發現這種方法最沒有反射。

相關問題