Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier
Transcript of Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier
![Page 2: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/2.jpg)
2Guy Smith-Ferrier
About…
Author of .NET Internationalization
– Visit http://www.dotneti18n.com to
download the complete source code
The .NET Developer Network
– http://www.dotnetdevnet.com
– Free user group for .NET developers,
architects and IT Pros based in Bristol
DDD South West
– http://www.dddsouthwest.com
– Taunton, Saturday 23rd May 2009
![Page 3: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/3.jpg)
3Guy Smith-Ferrier
Agenda
Dynamically Typed Objects
Optional And Named Parameters
Improvements To COM Support
Co- and contra-variance
Beyond C# 4
![Page 4: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/4.jpg)
4Guy Smith-Ferrier
Dynamic Type
dynamic myInt = 1;
myInt = "Hello World";
CultureInfo cultureInfo;
dynamic myVar = 1033;
cultureInfo = CultureInfo.GetCultureInfo(myVar);
myVar = "en-US";
cultureInfo = CultureInfo.GetCultureInfo(myVar);
System.Console.WriteLine(cultureInfo.Name);
object myInt = 1;
myInt = "Hello World";
![Page 5: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/5.jpg)
5Guy Smith-Ferrier
Consuming JavaScript Dynamic
Types From Silverlight (1 of 4)<html>
<head>
<title>SilverlightApplication1</title>
<script type="text/javascript">
var map;
function CreateMap() {
map = new VEMap("myMap");
map.LoadMap();
}
function UpdateMap(latitude, longitude) {
map.DeleteAllShapes();
var x = new VELatLong(latitude, longitude);
var pin = map.AddPushPin(x);
map.SetCenterAndZoom(x, 9);
}
</script>
![Page 6: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/6.jpg)
6Guy Smith-Ferrier
Consuming JavaScript Dynamic
Types From Silverlight (2 of 4)
public partial class Page1 : Page
{
HtmlWindow htmlWindow = HtmlPage.Window;
public void Init()
{
htmlWindow.Invoke("CreateMap");
}
void Customers_SelectionChanged(
object sender, SelectionChangedEventArgs args)
{
Customer customer = customers.SelectedItem as Customer;
HtmlDocument htmlDocument = HtmlPage.Document;
htmlDocument.SetProperty("Title", customer.Name);
htmlWindow.Invoke("UpdateMap",
customer.Latitude, customer.Longitude);
}
}
![Page 7: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/7.jpg)
7Guy Smith-Ferrier
Consuming JavaScript Dynamic
Types From Silverlight (3 of 4)
public partial class Page1 : Page
{
dynamic htmlWindow = HtmlPage.Window.AsDynamic();
public void Init()
{
htmlWindow.CreateMap();
}
void Customers_SelectionChanged(
object sender, SelectionChangedEventArgs args)
{
Customer customer = customers.SelectedItem as Customer;
dynamic htmlDocument = HtmlPage.Document.AsDynamic();
htmlDocument.Title = customer.Name;
htmlWindow.UpdateMap(customer.Latitude, customer.Longitude);
}
}
![Page 8: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/8.jpg)
8Guy Smith-Ferrier
Consuming JavaScript Dynamic
Types From Silverlight (4 of 4)
dynamic map;
function void CreateMap() {
map = win.New.VEMap("myMap");
map.LoadMap();
}
function void UpdateMap(dynamic latitude, dynamic longitude) {
map.DeleteAllShapes();
dynamic x = win.New.VELatLong(latitude, longitude);
dynamic pin = map.AddPushPin(x);
map.SetCenterAndZoom(x, 9);
}
This syntax is
temporary
![Page 9: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/9.jpg)
9Guy Smith-Ferrier
Support For Dynamic Languages
In The .NET Framework 4.0
Dynamic Language Runtime
Expression Trees Dynamic Dispatch Call Site Caching
IronPython IronRuby C# VB.NET Others
Python Ruby .NET OfficeSilverlight
Python
Binder
Ruby
Binder
Object
Binder
Java
Script
Binder
COM
Binder
![Page 10: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/10.jpg)
10Guy Smith-Ferrier
Implementing IDynamicObject
The Goalstatic void Main(string[] args)
{
dynamic resource =
new DynamicallyTypedResXResource("Resource1.resx");
Console.WriteLine(resource.HelloWorld);
}
static void Main(string[] args)
{
dynamic resource =
new DynamicallyTypedDbResource("Resource1");
Console.WriteLine(resource.HelloWorld);
}
![Page 11: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/11.jpg)
11Guy Smith-Ferrier
Implementing IDynamicObject
The Solutionpublic class DynamicallyTypedResXResource: DynamicObject
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
public DynamicallyTypedResXResource(string resxFilename)
{
ResXResourceReader reader = new ResXResourceReader(resxFilename);
IEnumerator enumerator = reader.GetEnumerator();
while (enumerator.MoveNext())
{
DictionaryEntry entry = (DictionaryEntry) enumerator.Current;
dictionary.Add(entry.Key.ToString(), entry.Value);
}
}
public override object GetMember(GetMemberAction action)
{
return dictionary[action.Name];
}
}
"HelloWorld"
![Page 12: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/12.jpg)
12Guy Smith-Ferrier
DynamicObject Methods
public class DynamicObject : IDynamicObject
{
public virtual object GetMember(GetMemberAction action);
public virtual void SetMember(SetMemberAction action, object value);
public virtual bool DeleteMember(DeleteMemberAction action);
public virtual object Call(CallAction action, params object[] args);
public virtual object Convert(ConvertAction action);
public virtual object Create(CreateAction action, params object[] args);
public virtual object Invoke(InvokeAction action, params object[] args);
public virtual object Operation(OperationAction action, params object[] args);
}
![Page 13: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/13.jpg)
13Guy Smith-Ferrier
Benefits Of Dynamic Typing
Program against dynamically typed languages
using the same syntax as for static languages
– e.g. JavaScript from Silverlight
– Write code in .NET that traditionally has been
written in other languages (e.g. JavaScript)
Program against dynamic structures using the
same syntax as for static structures
– e.g. XML, DataSets
![Page 14: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/14.jpg)
14Guy Smith-Ferrier
Optional Parameters (1 of 2)
static void JoinUserGroup(string userGroupName, bool isFree, bool hasGreatSpeakers, bool hasSwag)
{
}
static void JoinUserGroup(string userGroupName, bool isFree, bool hasGreatSpeakers)
{
}
static void JoinUserGroup(string userGroupName, bool isFree)
{
}
static void JoinUserGroup(string userGroupName)
{
}
![Page 15: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/15.jpg)
15Guy Smith-Ferrier
Optional Parameters (2 of 2)static void JoinUserGroup(
string userGroupName,
bool isFree = true,
bool hasGreatSpeakers = true,
bool hasSwag = true)
{
}
static void Main(string[] args)
{
JoinUserGroup("DotNetDevNet", true, true, true);
JoinUserGroup("DotNetDevNet", true, true);
JoinUserGroup("DotNetDevNet", true);
JoinUserGroup("DotNetDevNet");
}
![Page 16: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/16.jpg)
16Guy Smith-Ferrier
Named Parametersstatic void Main(string[] args)
{
JoinUserGroup("NxtGen", isFree: false);
JoinUserGroup("DotNetDevNet",
hasSwag: true, isFree: true, hasGreatSpeakers: true);
}
![Page 17: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/17.jpg)
17Guy Smith-Ferrier
Improved COM Support
Dynamic Type
Optional and named parameters
Support for COM indexed properties
ref modifier is now optional
Type Equivalence and Type Embedding (NoPIA)
Improvements in COM event handling
![Page 18: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/18.jpg)
18Guy Smith-Ferrier
Dynamic Types And COM
When you import a type library in .NET 4
you can choose whether to import types as
object (.NET 1 to 3.5) or dynamic (.NET 4)
// C# 1 to 3.5
((Excel.Range)excel.Cells[1, 1]).Value2 = "Hello";
Excel.Range range = (Excel.Range)excel.Cells[1, 1];
// C# 4 (type library imported with dynamic types)
excel.Cells[1, 1].Value = "Hello";
Excel.Range range = excel.Cells[1, 1];
![Page 19: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/19.jpg)
19Guy Smith-Ferrier
Optional and Named
Parameters And COM// C# 1 to 3.5
Excel.Chart chart = (Excel.Chart)
excel.Application.Charts.Add(Type.Missing, excel.ActiveSheet, Type.Missing, Type.Missing);
// C# 4
Excel.Chart chart =
excel.Application.Charts.Add(After: excel.ActiveSheet);
![Page 20: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/20.jpg)
20Guy Smith-Ferrier
ref Modifier Is Optional
// C# 1 to 3.5
var missing = Type.Missing;
word.Documents.Add(ref missing, ref missing, ref missing,
ref missing);
// C# 4
word.Documents.Add();
![Page 21: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/21.jpg)
21Guy Smith-Ferrier
Type Embedding (1 of 4)
Types from COM type
libraries can be
optionally embedded in
the assembly
The default will be
True for new projects
![Page 22: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/22.jpg)
22Guy Smith-Ferrier
Type Embedding (2 of 4) No Primary Interop Assembly (PIA) is required
Partial 'local' versions of the types are copied
into the assembly
Primary
Interop
Assembly
Visual Studio
(Intellisense)
C# Compiler
Assembly
Local Types
![Page 23: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/23.jpg)
23Guy Smith-Ferrier
Type Embedding (3 of 4)
Only the methods used
by the application are
included in the
interface
– all other methods are
represented by 'vtable
gaps'
![Page 24: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/24.jpg)
24Guy Smith-Ferrier
Type Embedding (4 of 4)
Only types from interop assemblies can be
embedded
– Assemblies must have the following attributes:-
Only metadata is embedded
– interfaces, delegates, enums, simple structs
– Classes cannot be embedded
[assembly:Guid()]
[assembly:ImportedFromTypeLib()]
![Page 25: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/25.jpg)
25Guy Smith-Ferrier
Type Equivalence
Interfaces that have the same GUID are
treated as equivalent types by the CLR
– At least one of the interfaces must have a
TypeIdentifier attribute
– .NET languages (C#, Visual Basic.NET etc.)
require the namespace to be the same
Structs also support type equivalence
– Full Trust is required
– Full Trust may be required for interfaces in a
future CTP
![Page 26: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/26.jpg)
26Guy Smith-Ferrier
Benefits Of Type Embedding
And Type Equivalence (NoPIA)
Smaller deployment footprint
– Office 2007 PIA footprint is 6.3Mb
Lower memory requirement
Develop against one version of Office (e.g.
2003) and run against a different version
(e.g. 2007)
![Page 27: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/27.jpg)
27Guy Smith-Ferrier
COM Event Handling (1 of 2)
The compiler now recognises subscription
to COM events and generates different code
The new code does not suffer from "ghost
RCWs" (Runtime Callable Wrapper)
Excel.Application excelApplication = new Excel.Application();
excelApplication.SheetSelectionChange += SheetSelectionChange;
![Page 28: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/28.jpg)
28Guy Smith-Ferrier
COM Event Handling (2 of 2)ComEventsHelper.Combine(excelApplication,
new Guid("00024413-0000-0000-C000-000000000046"),
0x616,
new AppEvents_SheetSelectionChangeEventHandler(
WindowsApplication1.SheetSelectionChange));
[Guid("00024413-0000-0000-C000-000000000046")]
public interface AppEvents
{
[DispId(2612)]
void AfterCalculate();
[DispId(1558)]
void SheetSelectionChange(object Sh, Range Target);
[DispId(1556)]
void WindowActivate(Workbook Wb, Window Wn);
![Page 29: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/29.jpg)
29Guy Smith-Ferrier
Co-Variance And Contra-Variance// C# 1, 2, 3, 3.5 and 4
IList<string> strings = new List<string>();
// Cannot implicitly convert type
IList<object> objects = strings;
// this is illegal because objects[0] is strings[0]
objects[0] = 42;
IList<string> strings = new List<string>();
// this will work in a future version of C# 4
IEnumerable<object> objects = strings;
![Page 30: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/30.jpg)
30Guy Smith-Ferrier
Co-Variance (out modifier)
public interface IEnumerable<out T>: IEnumerable
{
IEnumerator<T> GetEnumerator();
}
![Page 31: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/31.jpg)
31Guy Smith-Ferrier
Contra-Variance (in modifier)
public interface IComparer<in T>: IEnumerable
{
public int Compare(T left, T right);
}
![Page 32: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/32.jpg)
32Guy Smith-Ferrier
Variance Limitations
Variance type parameters can only be
declared on interfaces and delegates
Variance only applies when there is a
reference conversion
– IEnumerable<int> to IEnumerable<object> is a
boxing conversion not a reference conversion
![Page 33: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/33.jpg)
33Guy Smith-Ferrier
Beyond C# 4
Compiler As A Service (1 of 4)
public class CSharpEvaluator
{
public CSharpEvaluator();
public CSharpEvaluator(CSharpCompiler compiler);
public Collection<assembly> References { get; }
public Collection<string> Usings { get; }
public void Clear();
public EvaluationResult Eval(string program);
public bool IsComplete(string program);
}
![Page 34: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/34.jpg)
34Guy Smith-Ferrier
Beyond C# 4
Compiler As A Service (2 of 4)
public class EvaluationResult
{
public EvaluationResult(
object value, IList<ICSError> errors);
public IList<ICSErrors> Errors { get; }
public object Value { get; }
public override string ToString();
}
![Page 35: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/35.jpg)
35Guy Smith-Ferrier
Beyond C# 4
Compiler As A Service (3 of 4)
static void Main(string[] args)
{
CSharpEvaluator evaluator = new CSharpEvaluator();
evaluator.Usings.Add("System");
EvaluationResult result = evaluator.Eval("1 + 2");
Console.WriteLine(result);
}
![Page 36: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/36.jpg)
36Guy Smith-Ferrier
Beyond C# 4
Compiler As A Service (4 of 4)public class CSharpCompiler
{
public CSharpCompiler();
public BoundAssembly Bind(...);
public CompileResult Compile(...);
public CompileResult CompileTextIntoAssembly(...);
public CompileResult CompileTextToAssembly(...);
public CompileResult CompileToAssembly(...);
public void Emit(...);
public void EmitIntoAssembly(...);
public Assembly EmitToAssembly(...);
public SyntaxDocument Parse(...);
}
![Page 37: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/37.jpg)
37Guy Smith-Ferrier
Uses For "Compiler As A
Service"
Read-Eval-Print Loop (REPL)
C# scripting (runtime extensibility)
– Embed C# in Domain Specific Languages
e.g. Windows Workflow code snippets
Meta programming
Language Object Model
– To enable C# refactoring
![Page 38: Internationalizing WPF And Silverlight Applications - Guy Smith-Ferrier](https://reader030.fdocuments.us/reader030/viewer/2022021009/6203aafdda24ad121e4c12c0/html5/thumbnails/38.jpg)
38Guy Smith-Ferrier
Summary
Dynamically Typed Objects
Optional And Named Parameters
Improvements To COM Support
Co- and contra-variance
Beyond C# 4