2013-05-02 58 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将会已使用

您可以对照用动态加载和反射来完成所有这些事情(少量代码行),但使用起来有点笨重。我发现这种方法最没有反射。

相关问题