2013-05-02 2 views
1

매우 구체적인 재무 계산을 위해 작은 C# /. net 라이브러리를 작성하려고합니다.어셈블리 참조가 C#에 있는지 프로그래밍 방식으로 확인하는 방법?

.net 프레임 워크의 표준 어셈블리에만 의존하는 여러 클래스를 작성했습니다. 즉, 이러한 클래스가있는 라이브러리는 .net 프레임 워크 (4.0 클라이언트) 이외의 다른 것을 필요로하지 않습니다.

이제 Excel 통합을위한 추가 클래스가 필요합니다. 이 클래스는 Microsoft Office와 관련된 추가 어셈블리 참조가 필요하며 각 개체 라이브러리와 마찬가지로 Excel이 필요합니다.

내 문제는 :이 라이브러리의 사용자 중 일부는 사무실에있을 수 있으며 일부는 Excel 수 있습니다.

두 가지 유형의 사용자가 오류없이 라이브러리를 사용할 수 있도록이 추가 클래스를 라이브러리에 추가하려면 어떻게해야합니까?

더 정확하게 말하자면 : 사용자가 사무실이없고 Excel이없는 경우 오류가 발생하지 않고 Excel 관련 항목을 제외한 모든 클래스를 실행할 수 있어야합니다. 어떤 도움

덕분에, selmar

답변

2

이 상자 밖으로 작동합니다. 어셈블리는 필요할 때로드됩니다. 즉 필요할 때로드됩니다. Excel이없는 사용자가 Excel 관련 클래스를 사용하지 않는 한 오류가 없어야합니다.

+0

코드 상단의 참조 사용은 어떻습니까? Excel을 사용하는 = Microsoft.Office.Interop.Excel; 사무실이없고 컴퓨터를 능가하는 사용자에게 어셈블리 참조 오류가 발생하지 않습니까? – selmar

+1

@selmar : 어셈블리는 사용 된 경우에만로드됩니다. '사용하는 것만으로는 충분하지 않습니다. 실제로 어셈블리에서 형식을 열거하거나 인스턴스화해야합니다. –

0

ILMerge을 사용해 보셨습니까? 이렇게하면 필요한 dll을 실행 파일에 추가 할 수 있으므로 사용자에게 필요한 어셈블리가 있는지 확인할 수 있습니다.

+0

좋은 생각이지만 Microsoft 오브젝트 라이브러리와 같은 dll을 배포하는 것이 합법적입니까? – selmar

+0

내 생각에, y 마이크로 소프트를 만들었습니다. 페이지의 어떤 것도 그 반대가 아닙니다. –

3

저는 실제로 이와 같은 작업을 수행하고있었습니다. 어셈블리가 존재하거나 작동 할 경우 프로빙되었습니다.

당신은 물론 여러 가지 방법으로이 작업을 수행 할 수 있지만 내가 끝났다 무엇 : 인터페이스에이 클래스의 모든 기능을 추출

  • (현실을 부르 자 : IExcel를)하고 그것에 IsAvailable 속성을 추가
  • IExcel을 구현하고 IsAvailable에서 'false'를 반환하는 가짜 클래스를 구현했습니다. 물론 다른 메서드에서 NotSupportedException을 throw합니다.
  • 새 어셈블리 (중요 : NEW ASSEMBLY) 만들기 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; 
    } 
} 

조립품 : 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이됩니다. 중고

동적 로딩과 리플렉션 (코드 라인이 적음)을 사용하여 모든 것을 수행하지만 사용하기에는 조금 어색함. 나는이 방법을 가장 반사가 적은 것으로 발견했다.

관련 문제