2013-05-02 3 views
1

Я пытаюсь написать небольшую библиотеку C# /. Net для очень конкретных финансовых расчетов.Как проверить программно, если ссылка на сборку существует в C#?

Я написал несколько классов, которые зависят только от стандартных сборок .net framework. То есть библиотека с этими классами не требует ничего, кроме .net framework (4.0 client).

Теперь мне нужен дополнительный класс для интеграции с excel. Этот класс потребует дополнительных ссылок на сборку, связанных с офисом Microsoft и Excel, как и их соответствующие библиотеки объектов.

Моя проблема: некоторые пользователи этой библиотеки могут иметь офис и преуспеть, некоторые нет.

Как добавить этот дополнительный класс в библиотеку, чтобы оба типа пользователей могли использовать библиотеку без ошибок?

Точнее: если пользователь не имеет офиса и имеет преимущество, пользователь должен иметь возможность запускать все классы, исключая excel-related, без ошибок.

спасибо за любую помощь, Selmar

ответ

2

Это должно работать из коробки. Ассембли загружаются по требованию, т. Е. Загружаются, когда это необходимо. Пока пользователи без Excel не используют класс, связанный с Excel, не должно быть ошибок.

+0

Как насчет ссылки на использование в верхней части кода? с использованием Excel = Microsoft.Office.Interop.Excel; Не может ли это привести ошибку ссылки на сборку для пользователя, который не имеет офиса и превосходит его компьютер? – selmar

+1

@selmar: Ассембли загружаются только в том случае, если они используются. Недостаточно «использования». Вам действительно нужно перечислять или создавать экземпляры типов из сборки. –

0

Вы попробовали ILMerge? Это позволит вам добавить требуемую DLL в ваш исполняемый файл, чтобы вы были уверены, что у пользователя есть необходимые сборки.

+0

Хорошая идея, но является ли вообще законным распространение таких библиотек DLL, как библиотеки объектов Microsoft? – selmar

+0

Я так думаю, это построение y microsoft, ничто на страницах не говорит об обратном. –

3

Я действительно делал что-то вроде этого. Ассембли были исследованы, если они существуют/будут работать.

Вы можете сделать это во многих отношениях, конечно, но это то, что я закончил с:

  • Извлеченный все функциональные возможности этого класса в интерфейс (назовем его: IExcel) и добавил IsAvailable собственности на него
  • Реализован поддельный класс, реализующий IExcel и возвращающий «false» из IsAvailable (и, конечно же, бросая NotSupportedException из других методов).
  • Создать новую сборку (важно: новый сборочный) с реальным осуществлением IExcel
  • Реализовать класс Factory с «Создать», который будет решать, какой из них должен быть возвращен и исключение подхват на решимостью (или тест)

Монтаж: 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; 
    } 
} 

Монтаж: 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 не найдена (вы ее не включили), она не сработает, когда RealExcel будет создан в MyFacade, поэтому FakeExcel будет использовано

Вы можете из курса se делает все эти вещи с динамической загрузкой и отражением (меньше строк кода), но немного неуклюже в использовании. Я нашел этот метод наиболее безразличным.

Смежные вопросы