2009-11-04 6 views

답변

5

다른 컴파일러를 사용하여 Silverlight 및 Silverlight 이외의 어셈블리를 만드는 경우 컴파일러 지시문을 사용하고 런타임에 차이를 감지하는 대신 조건부로 코드를 컴파일 할 수 있습니다. 그냥 SILVERLIGHT을 정의 (또는 다른 정의) 실버 빌드하고 있습니다

#if SILVERLIGHT 
// Do silverlight stuff 
#else 
// Do other stuff 
#endif 

당신은이 방법으로뿐만 아니라 ConditionalAttribute를 사용할 수 있습니다.

6

Jeff's solution은 직접 작동하며 작동합니다. 그러나 코드 전체에 #if 컴파일러 지시문을 사용하는 것이 바람직하지 않은 경우 약간의 인터페이스 마법으로 모든 것을 집중화하고 추상화 할 수 있습니다.

은 소비자

public class MyClass 
{ 
    private readonly IRuntimeInfo _runtimeInfo = null; 
    public MyClass (IRuntimeInfo runtimeInfo) 
    { 
     _runtimeInfo = runtimeInfo; 
    } 
    public void SomeMethod() 
    { 
     if (_runtimeInfo.IsSilverlight) 
     { 
      // do your thang 
     } 
     else 
     { 
      // do some other thang 
     } 
    } 
} 

을에

public class RuntimeInfo : IRuntimeInfo 
{ 
    public bool IsSilverlight { get; private set; } 
    public RuntimeInfo() 
    { 
     // @Jeff's compiler directives - er, taking his 
     // word 'SILVERLIGHT' is actually defined 
     #if SILVERLIGHT 
      IsSilverlight = true; 
     #else 
      IsSilverlight = false; 
     #endif 
    } 
} 

같은 구현

// a nice neat public interface to centralize all of your 
// run time requirements 
public interface IRuntimeInfo 
{ 
    // true if silverlight runtime, false if full-Clr 
    bool IsSilverlight { get; } 
} 

, 다음 사항을 고려하고 지금은 실제 런타임의 독립적 인 테스트 할 수 있습니다

이제 컨테이너에서, 팩토리 또는 기본 생성자를 사용하여 구체적인 구현이 통과되도록 할 수 있습니다. 예를 들어, 재 방문 MyClass에는, 위에서 확실히 작동합니다 전처리 지시어를 사용

public class MyClass 
{ 
    // default constructor. personally, I would opt to use a container 
    // like Castle Windsor Container, or Microsoft's Unity, but if you 
    // have no control over application or it's just this "one" thing, 
    // just default to a concrete implementation below. 
    public MyClass() : this (new RuntimeInfo()) { } 
    // what we call an "injector" constructor, because runtime info is 
    // passed - or "injected" - into instance. 
    public MyClass (IRuntimeInfo runtimeInfo) { ... } 
    ... 
} 
+0

+1 매우 좋은 답변입니다. – TheMissingLINQ

+0

좋은 점이 있지만 #if 요소 (이 코드를 숨기고 싶은 이유는 모르겠지만)가 숨겨져 있지만 Silverlight 배포 용 어셈블리가 두 버전 모두 포함되므로 결과적으로 어셈블리가 더 커질 수 있습니다. 또한 두 가지 용도로만 존재하는 유형 만 사용할 수 있음을 의미합니다. –

+0

트레이드 오프입니다. 필자는 테스트하기 어렵 기 때문에 컴파일러 지시문을 사용하지 않습니다. [응용 프로그램 동작을 정확하게 테스트하려면 모든 지시문을 철저히 분석해야합니다.] 어셈블리 팽창, 유형 가용성 등과 같은 고려 사항도 작성해야합니다. 그러나 이는 사용자의 책임입니다. 이것은 단지 * 하나 * 가능한 해결책입니다 :) –

0

제안 된 솔루션을 니펫을하지만, 단지 기본 클래스를 작성하는 것입니다 간단한 해결책처럼 보인다 후 실버 라이트를 모두 도출 및 Silverlight가 아닌 버전이 포함되어 있습니다. 전반적으로 코드의 가독성을 높이는 것은 물론, 그렇게 유지하고 테스트하는 것이 훨씬 쉬울 것이라고 생각합니다.

런타임 환경을 기반으로하는 문장이 Javascript 프로그래밍에 관한 모든 최악의 상황을 싫어하며 필자는 프로젝트를 볼 필요가없는 곳에서 코드를 작성하는 것이 싫다. 그 길은 위험합니다.

관련 문제