2011-03-01 1 views
8

우리는 Windows에서 C# 및 .NET 4.0을 사용하여 Visual Studio 2010에서 여러 응용 프로그램을 개발하고 있습니다. 여러 WCF 프로젝트의 서비스를 사용하는 두 개의 SilverLight 응용 프로그램. 다른 하나는 콘솔 응용 프로그램입니다.C# Library Code가 System.Web.dll없이 응용 프로그램 유형을 호스팅하는 것을 어떻게 알 수 있습니까?

코드를 인수 분해하고 재사용하기 위해 분리 된 라이브러리 프로젝트에 "공통"기능을 추가하려고합니다. 이 라이브러리는 WCF 서비스처럼 응용 프로그램 (IIS, ASP.NET ...)이 호스팅되는지 또는 다른 파일 경로 처리로 인해 콘솔 응용 프로그램으로 실행되는지를 알아야합니다.

이 질문을하는 사람들은 HttpContext, HostingEnvironment.IsHosted를 사용하여 코드가 호스팅되는지를 알기 위해 System.Web.dll을 사용함을 나타냅니다. 문제는 이러한 접근 방식이 시스템에 대한 참조를 포함해야한다는 것입니다 .Web int이 라이브러리가 클라이언트 프로파일이있는 콘솔 프로젝트에서 참조되는 경우 허용되지 않습니다.

아이디어는 System.Web 어셈블리를 사용하지 않는 다른 기술을 사용하는 것입니다.

+0

"다른 파일 경로 처리로 인한 것"- 파일 경로 처리가 ASP.NET과 콘솔 응용 프로그램간에 다를 필요는 없습니다. 왜 필요하다고 생각하는지 정확하게 설명하면 누군가가 호스팅 앱에 대해 알 필요가있는 클래스 라이브러리를 피할 수있는 솔루션을 게시 할 수 있습니다. – Joe

+0

라이브러리가 호스트 된 경우, 라이브러리/애플리케이션과 같은 폴더에있는 파일의 경로를 얻기 위해 가상 경로를 실제 경로에 매핑하려면'HostingEnvironment.MapPath ("~ /"+ fileName)'이 필요합니다 ; 콘솔 응용 프로그램을 실행할 때 'filename'을 상대 경로로 사용하십시오. –

+0

내 대답보기, 당신은 AppDomain.BaseDirectory를 사용하여 응용 프로그램 폴더를 얻을 수 있습니다. – Joe

답변

8

, 당신은 사용할 수 있습니다

Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "filename") 

을 ASP.NET 응용 프로그램의 경우,이 뜻을 루트 폴더 (MapPath ("~ /"+ filename)와 같음)이면 콘솔 응용 프로그램의 경우 실행 파일이 들어있는 폴더가됩니다. 원래의 질문에 대한 코멘트에서

:

A는 콘솔 응용 프로그램으로, 단지 상대 경로로 파일 이름을 사용하여 실행

나는 상대 경로를 사용하지 않는 것이 좋습니다 것이다. 이것은 응용 프로그램 디렉토리와 같지 않은 현재 작업 디렉토리에 상대적입니다.

0

Silverlight 및 콘솔 응용 프로그램은 자신의 환경을 알게되므로 관련 정보를 App.config 파일에 넣을 수 있으므로 공용 라이브러리가 자체적으로 작업하지 않고 구성을 통해 환경 정보에 액세스 할 수 있습니다 .

+0

확실하지 않습니다. .NET을 처음 사용하고 콘솔 응용 프로그램 프로젝트에는 기본적으로 .config 파일이 없습니다. 라이브러리는 주로 WCF 서비스에 사용되며 외부 파일이 아닌 코드 만 포함하는 솔루션을 찾고 있습니다. –

+0

콘솔 응용 프로그램과 함께 App.config 파일을 사용할 수 있습니다. http://forums.asp.net/t/1168194.aspx/1?how+to+use+app+config+in+a+console+application – tjrobinson

0

아마도 가장 쉬운 방법은 라이브러리를 사용할 다른 응용 프로그램 유형의 라이브러리에서 열거 형을 만드는 것입니다. 열거 형을 사용하여 라이브러리에 변수를 만듭니다. 그런 다음 라이브러리를 사용하는 앱에 해당 열거 형 변수를 설정하게하면 라이브러리는 해당 열거 형을 사용하는 앱의 유형을 알게됩니다. 이처럼

: 또한 라이브러리 메소드 호출의 일부로서 요구되는 열거 형의 applicationType의 매개 변수를 확인하여 응용 프로그램 유형을 얻을 수

public static enum applicationType { hosted, console}; 
public static applicationType applicationConsumerType = applicationType.console; 

. 그렇다면 그것이 무엇이든지간에, 당신은 항상 알고 있습니다. 왜냐하면 그것은 필수 매개 변수이기 때문입니다.

+0

좋은 속임수이지만 목표는 WCF 프로젝트에서 모든 변수를 설정해야하기 때문에 라이브러리가 응용 프로그램을 사용하지 않고 (IIS 또는 콘솔에서 주로 호스팅되는) 어떤 종류의 응용 프로그램을 사용하고 있는지를 아는 것입니다. 응용 프로그램은 많은 시작 지점 (서비스)을 가지고 있으므로 첫 번째 서비스가 보장되지는 않습니다. –

+0

응용 프로그램은 응용 프로그램의 유형을 라이브러리에 표시해야합니다. 라이브러리는 개별적이고 독립된 코드 단위 (아마도)이기 때문에 그 자체로 알 수 없으며이를 호출하는 앱에 대해 알지 못합니다. 응용 프로그램은 파라미터 나 일종의 설정, XML 파일 (다른 포스터로 표시됨)을 통해 "알림"해야합니다. 그 방법으로 볼 수있는 문제는 라이브러리가 파일에 의존하도록하는 것입니다. 존재하지 않을 수도 있음), 또는 무언가. 아마도 라이브러리에서 호출 된 메소드에 전달되는 매개 변수를 enum으로 만듭니다. – richard

+0

부수적으로, 라이브러리는 응용 프로그램에 종속되지 않으므로 라이브러리가 자체적으로 사용중인 내용을 알 수 없습니다. 모듈의 매니페스트는 응용 프로그램의 파일에 대한 종속성이나 아무 것도 나타내지 않습니다.그래서 그것은 "정보 제공"되어야합니다 (반복되는 위험에 있습니다! LOL). – richard

1

반사을 사용하면 GetCallingAssembly 방법을 사용하여이를 수행 할 수 있습니다. 예

public string GetPath() 
{ 

if(Assembly.GetCallingAssembly().FullName == "WebProjectDLLName") 
{ 
    //From web project 
} 
else 
{ 
    // other than web project 
} 
} 

는 일반적인 해결책은 아니지만 들어, (어셈블리를 호출에)를 GetReferenceAssemblies 방법을 사용하여 향상시킬 수 있습니다.

+0

문제는 라이브러리가 여러 응용 프로그램의 "일반"라이브러리와 같이 누구가 응용 프로그램을 사용할 것인지를 모르는 것입니다. –

+0

'GetReferenceAssemblies'에서'System.Web'이로드되었음을 쉽게 알 수 있습니다. – Adeel

4

또 다른 반사 아이디어 : System.Web로드되어 있는지

  1. 사용 AppDomain.CurrentDomain.GetAssemblies(); System.Web하지만 반사를 통해를 사용 이로드되어있는 경우 그렇지 않은 경우, 당신은
  2. 를 호스팅하지 않는, 사용 반사 HostingEnvironment.IsHosted가


은 그 이상이 수행하는 것을 쉽게 밝혀 호출하지만,이 트릭을 할 것 같다 :

public static bool IsHosted() 
{ 
    try 
    { 
    var webAssemblies = AppDomain.CurrentDomain.GetAssemblies() 
     .Where(a => a.FullName.StartsWith("System.Web")); 
    foreach(var webAssembly in webAssemblies) 
    { 
     var hostingEnvironmentType = webAssembly.GetType("System.Web.Hosting.HostingEnvironment"); 
     if (hostingEnvironmentType != null) 
     { 
     var isHostedProperty = hostingEnvironmentType.GetProperty("IsHosted", 
      BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.Public); 
     if (isHostedProperty != null) 
     { 
      object result = isHostedProperty.GetValue(null, null); 
      if (result is bool) 
      { 
      return (bool) result; 
      } 
     } 
     } 
    } 
    } 
    catch (Exception) 
    { 
    // Failed to find or execute HostingEnvironment.IsHosted; assume false 
    } 
    return false; 
} 

반영이 비싸므로 한 번 실행하고 결과를 캐시하십시오. 특정 어셈블리와 유형을 찾는 가장 좋은 방법은 무엇 인지도 모르겠지만이 방법이 효과적입니다.당신은 단지 (질문에 대한 주석에서와 같이) 응용 프로그램을 포함하는 폴더에있는 파일의 경로를 얻을 필요가있는 경우

+0

Java에서와 마찬가지로, .NET의 Reflection 기능이 빠져 있습니다! –

8

응용 프로그램이 ASP.NET인지 확인하는 방법에는 여러 가지가 있습니다.

확인 구성 파일

if ("web.config".Equals(Path.GetFileName(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile), StringComparison.OrdinalIgnoreCase)) 
{ 
    // ASP.NET application 
} 

ASP.NET 응용 프로그램의 이름은

if (Assembly.GetEntryAssembly() == null) 
{ 
    // ASP.NET application 
} 

ASP.NET 응용 프로그램의 모든 .dll 파일의 섀도 복사본을 사용하는 항목 조립이 없습니다. 그러나 다른 유형의 응용 프로그램에서 이것이 가능한지 확실하지 않습니다.

if (AppDomain.CurrentDomain.ShadowCopyFiles) 
{ 
    // ASP.NET application (probably) 
} 
+0

Visual Studio에서 웹 서비스를 디버깅 할 때 여전히 작동하기 때문에 web.config 메서드가 마음에 들었습니다. – Hagelt18

관련 문제