Ressourcen aus externen Libraries im Markup ausgeben
Bei großen Projekten kann es unter Umständen Sinn machen, alle String-Ressourcen in eine separate Library auszulagern. Das Problem ist dann nur, dass diese Ressourcen nicht mehr so einfach über die ASP.NET Markup angesprochen werden können.
Die Lösung gibt es mit einem eigenen ExpressionBuilder, mit dem es möglich ist einen eigenen ASP.NET Ausdruck zu schreiben um auf die externen Ressourcen zu zu greifen.
<%$ ExternalResources: General, LoginPageTitle %>
Um den Ausdruck von eventuellen internen Ressourcen auseinander zu halten habe ich den ExpressionPrefix “ExternalResources” genannt.
Die Struktur des xpressionBuilder sieht bei mir wie folgt aus:
[ExpressionPrefix("ExternalResources")]
public class ExternalResourcesExpressionBuilder:
ExpressionBuilder
{
public override object ParseExpression(
string expression,
Type propertyType,
ExpressionBuilderContext context)
{
}
public override CodeExpression GetCodeExpression(
BoundPropertyEntry entry,
object parsedData,
ExpressionBuilderContext context)
{
}
}
die Methode ParseExpression nimmt den Ausdruck auseinander und gibt diesen in einem gewünschten Format als Object zurück. In meinem Fall habe ich mir eine kleine Hilfsklasse namens “ResourceExpression” gebaut:
classKey = null;
string resourceKey = null;
if(expression.Length != 0)
{
string[] strArray = expression.Split(new[] { ',' });
int length = strArray.Length;
if(length > 2)
{
return null;
}
if(length == 1)
{
resourceKey = strArray[0].Trim();
}
else
{
classKey = strArray[0].Trim();
resourceKey = strArray[1].Trim();
}
}
return new ResourceExpression
{
ClassKey = classKey,
ResourceKey = resourceKey
};
Die Hilfsklasse:
public class ResourceExpression
{
public string ClassKey { get; set; }
public string ResourceKey { get; set; }
}
In der Methode “GetCodeExpression” findet die eigentliche Arbeit statt. Hier wird der Ressource-String ermittelt und zurückgegeben. Theoretisch kann hier auch per WebService auf einen Übersetzungsdienst zu gegriffen werden.
Ich hole mir allerdings nur per Reflection den entsprechenden ResoourceManager über den ich den zurück zu gebenden Ressource-String ermittle:
ResourceExpression expression = (ResourceExpression)parsedData;
ResourceManager resourceManager = new ResourceManager("Cobra.Web.Resources." + expression.ClassKey, Assembly.GetAssembly(typeof(Resources.General)))
{
IgnoreCase = true
};
string outString = String.Empty;
if(!string.IsNullOrEmpty(expression.ResourceKey))
{
outString = resourceManager.GetString(expression.ResourceKey);
}
return new CodePrimitiveExpression(outString);
Zu guter Letzt, muss der ExpressionBuilder noch in Web.Config registriert werden:
<configuration>
<system.web>
<compilation>
<expressionBuilders>
<add expressionPrefix="ExternalResources"
type="GO.Web.Library.ExternalResourcesExpressionBuilder"/>
</expressionBuilders>
</compilation>
</system.web>
</configuration>