2012-04-24 3 views
0

우리는 웹 사이트에서 제출 한 작업 작업 서버를 보유하고 있습니다. 웹 사이트의 어셈블리는 패키징되어 작업의 일부로 작업 서버에 제출됩니다 (모든 위성 리소스 어셈블리 포함).주어진 리소스의 모든 리소스 값 스냅 샷 런타임시 키

이러한 어셈블리는 작업 처리가 시작되기 전에 Assembly.Load (byte [])를 통해로드됩니다.

작업 처리 중에 리소스 문자열 (즉, 유효성 검사 메시지)을 스냅 샷하려는 지점에 도달합니다. 유효성 검사 규칙/메시지가 시간이 지남에 따라 변경 될 수 있고 이전에 처리 된 작업/메시지를보기 위해 다시 돌아 왔기 때문에 리소스 키를 저장하는 것이 옵션이 아니라는 점에 유의하십시오. 작업 처리가 표시 될 때 값이 필요합니다. 웹 사이트 스레드가 실행중인 적절한 문화권에 메시지를 표시 할 수 있도록 지원되는 각 문화권 메시지의 스냅 샷이 필요합니다.

var resourceType = Type.GetType("BTR.Websites.MadHatter.Clients.ABCCorp.Resources.ClientStrings"); 
var rm = resourceType != null ? new ResourceManager(resourceType) : null; 

이 잘하는 I 작동 : 시도하고 메시지를 검색하려면

는 웹 사이트 어셈블리 작업 서버에 그래서, 나는 웹 사이트 어셈블리의 ResourceManager에 만들려면이 같은 일을, 로케일이 지원되는 지정 는 ResourceManager는, 그러나, XElement를 validationRule 및 문자열 [] 로케일을 주어, 다음 코드는 '작동하지 않는'얻을 :

validationRule.Add( 
    from l in locales 
    let message = rm.GetString(p.Value.ToString(), new CultureInfo(l)) 
    select new XAttribute(string.Format("Message.{0}", l), message)); 

기본적으로 아무리 CultureInfo를 내가에서 통과 무엇을, 나는 기본 (EN-를 얻을 미국) 문화의 메시지.

AppDomain.CurrentDomain.GetAssemblies()로드 된 웹 사이트 어셈블리와 위성 어셈블리를 모두 보여줍니다

{ABCCorp.ServiceModel, 버전 = 6.0.4497.18334을, 문화 = 중립, PublicKeyToken = NULL} System.Reflection.Assembly { System.Reflection.RuntimeAssembly} {ABCCorp.ServiceModel.resources, 버전 = 6.0.4497.18334, 문화 = FR-FR은, PublicKeyToken = NULL} System.Reflection.Assembly {System.Reflection.RuntimeAssembly}

그러나 나는 시도하는 경우 시계 창 (위의 코드와 동일)에서 다음과 같이하면 en-US 버전을 얻을 수 있습니다.

rm.GetString ("ResourceKey", new CultureInfo ("fr-FR"))

마지막으로 우리는 모두 LINQPad에 대해 잘 알고 있습니다 :) 다음 스크립트는 작동합니다. 나는 ABCCorp의 ServiceModel.dll이나 위성 dll에 대한 언급이 없다.

Assembly.LoadFile(@"C:\BTR\Source\ABCCorp.ServiceModel.dll"); 
Assembly.LoadFile(@"C:\BTR\Source\fr-FR\ABCCorp.ServiceModel.resources.dll"); 
AppDomain.CurrentDomain.GetAssemblies().Dump(); 
var resourceType = Type.GetType("BTR.Websites.MadHatter.Clients.ABCCorp.Resources.ClientStrings, ABCCorp.ServiceModel").Dump(); 
var rm = resourceType != null ? new ResourceManager(resourceType) : null; 
rm.GetString("FlatMemberInformationBasicInformation_DateDeathProof", new CultureInfo("fr-FR")).Dump(); 

제안 사항은 크게 반갑습니다.

업데이트 : 다음은 Joe의 제안을 바탕으로 작성한 코드입니다. byte [] content는 웹 사이트 어셈블리와 모든 위성 자원 어셈블리가있는 zip 파일입니다.

private Assembly LoadPackagedAssembly(byte[] content) 
{ 
    var loaded = new Dictionary<string, Assembly>(); 

    AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs args) 
    { 
     return loaded.ContainsKey(args.Name) 
      ? loaded[ args.Name ] 
      : null; 
    }; 

    Assembly mainAssembly = null; 

    using (var stream = new MemoryStream(content)) 
    { 
     using (var zip = new ZipInputStream(stream)) 
     { 
      ZipEntry entry; 

      while ((entry = zip.GetNextEntry()) != null) 
      { 
       using (var buffer = new MemoryStream()) 
       { 
        Streams.CopyStream(zip, buffer); 

        var assembly = Assembly.Load(buffer.ToArray()); 

        loaded[ assembly.FullName ] = assembly; 

        if (mainAssembly == null) mainAssembly = assembly; 
       } 
      } 
     } 
    } 

    return mainAssembly; 
} 
+0

'rm.GetResourceSet()'이 (가) 같은 culture에 대해 반환하는 것은 무엇입니까? – dez

답변

0

어셈블리 해상도 문제인 것 같습니다. Load (byte []) 및 LoadFile을 사용하면 no binding context이됩니다. 즉, LoadFrom을 사용하거나 AppDomain의 AssemblyResolve 이벤트를 처리하여이를 처리하십시오.

LINQPad는 다른 위치에서 동일한 DLL을 간접적으로 참조함으로써 발생하는 문제를 해결하기 위해 AssemblyResolve 이벤트를 처리합니다.이것의 부작용은 바인딩이 실패 할 시나리오에서 바인딩 컨텍스트를 융합 시켜서 그렇지 않은 경우 작동하도록 만듭니다.

+0

이 조를 보아 주셔서 감사합니다. 우리 문제를 해결했습니다. – Terry