如何以编程方式检查c#中是否存在程序集引用?

时间:2013-05-02 16:49:12

标签: .net c#-4.0 using assembly-references

我正在尝试编写一个小型的c#/ .net库,用于非常具体的财务计算。

我编写了几个仅依赖于.net框架标准程序集的类。也就是说,具有这些类的库只需要.net框架(4.0客户端)。

现在我需要一个额外的类来进行excel集成。这个类需要与microsoft office和excel相关的其他程序集引用,就像它们各自的对象库一样。

我的问题是:这个图书馆的一些用户可能有办公室和excel,有些则没有。

如何将此附加类添加到库中,以便两种类型的用户都可以使用该库而不会出错?

更确切地说:如果用户没有办公室和excel,用户必须能够运行除excel相关的所有类而不会出错。

感谢任何帮助,selmar

3 个答案:

答案 0 :(得分:3)

我其实是这样做的。调查组件是否存在/将起作用。

当然,你可以通过多种方式做到这一点,但这就是我的结果:

  • 将此类的所有功能提取到接口(让我们称之为:IExcel)并向其添加IsAvailable属性
  • 实现了实现IExcel的假类,并从IsAvailable返回'false'(当然,从其他方法抛出NotSupportedException)。
  • 使用IExcel的实际实现
  • 创建新程序集(重要:新装配)
  • 使用'Create'实现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程序集(您没有包含它),则在MyFacade中创建RealExcel时会失败,因此将使用FakeExcel

你当然可以通过动态加载和反射(更少的代码行)完成所有这些事情,但使用起来有点笨拙。我发现这种方法最无反射。

答案 1 :(得分:2)

这应该是开箱即用的。程序集按需加载,即在需要时加载。只要没有Excel的用户不使用Excel相关的类,就不会有错误。

答案 2 :(得分:0)

你试过ILMerge吗?这样您就可以将所需的dll添加到可执行文件中,这样您就可以确保用户具有所需的程序集