![Page 1: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/1.jpg)
Эффективное использование Dynamic
Language Runtime
Карлен Симонян разработчик
![Page 2: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/2.jpg)
О чем мы поговорим
� DLR как платформа – зачем? � Динамизм в .NET вчера, сегодня, завтра
� Продолжите ряд: IronPython, IronRuby, IronC#? � C# matters � DLR Inside Out
� Узлы вызовов aka callsites, PIC, кэширование, производительность и дополнительные затраты памяти, CPU, etc.
� DLR in the wild � Infinite loop
![Page 3: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/3.jpg)
DLR как платформа – Timeline
� 2004 � отсутствуют публично выпущенные динамические языки для .NET � до CLR 2.0 еще два года � Jim Hugunin присоединяется к Microsoft (будучи автором Jython и уже разрабатывая IronPython)
� На конференции OSCon 2004 показывается IronPython 0.6 � 2007
� На конференции MIX’07 показывается IronPython 1.0, анонсируется IronRuby с выходами первых альфа-версий в 2008
� Впервые вводится понятие Dynamic Language Runtime
![Page 4: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/4.jpg)
DLR как платформа – Timeline
� 2008 � DLR v0.9 � IronPython 2.0 � Две альфа версии IronRuby
� 2009 � IronPython 2.6 � IronRuby 0.9. Возможность запуска некоторых Rails-приложений
� 2010 � C# 4 � DLR v1.0 � .NET 4
� 2011 - 2014 � IronPython 2.7 � IronRuby 1.1 � Поддержка .NET 4.0+ � Возможности рантайма и кодогенерации в составе .NET 4+
![Page 5: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/5.jpg)
DLR как платформа
� Новый DLR добавляет важный набор возможностей в .NET, минуя изменения в CLR � Стандартную модель хостинга для динамических языков � Инфраструктуру для генерации быстрого кода
� .NET 3.5+ уже включает в состав System.Linq.Expressions – основу LINQ и кодогенерации DLR
![Page 6: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/6.jpg)
Продолжите ряд: IronPython, IronRuby, IronC#? � Несмотря на растущее количество динамических языков на .NET, эволюцию динамизма продолжил именно C#
� C# 4 является прямым продолжением развития темы Iron-языков, собрав в свойствах своего dynamic - возможности DLR
![Page 7: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/7.jpg)
.NET
TODAY DLR
TEXT
SECURITY
On Rails
SPEED
WEBAPPS DATA
CODE GENERATION
CALLSITES COMPILER
Ruby
DYNAMIC
CONTEXTS
CACHING RUNTIME
POLYMORPHIC
FAST
DESIGN
WPF FAST
POWERSHELL
UNIFIED
WEB COMMON
EVERYWHERE NLua
FRAMEWORK
CLR CACHING IronPython
HOSTING
POLYMORPHIC GC
ASP.NET
SYSTEM.DYNAMIC LIBRARY
IronJS
IronRuby
BASE
JIT
FUNCTIONS
EXPRESSIONS
CLASS
WEB
INLINE SYSTEM.LINQ.EXPRESSIONS
TEXT
HOSTING
AST
c#
INLINE BINDERS
RUNTIME IronLua
![Page 8: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/8.jpg)
C# Matters – Inside dynamic keyword
� Каждый dynamic параметр/переменная является System.Object � Любые операции, связанные с использованием ключевого слова dynamic сопровождаются использованием узлов вызовов aka callsites.
� Callsite выступает в качестве: � Getter/Setter для:
� Fields � Properties � Indexers
� Method/Delegate invoker � Унарной/бинарной операции � Операции конвертации/приведения типов
![Page 9: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/9.jpg)
object d = 100; object arg = d; if (Program.<dynamicMethod>o__SiteContainerd.<>p__Sitee == null) { Program.<dynamicMethod>o__SiteContainerd.<>p__Sitee = CallSite<Func<CallSite, object, object>>.Create( Binder.UnaryOperation(CSharpBinderFlags.None, ExpressionType.Increment, typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) })); } d = Program.<dynamicMethod>o__SiteContainerd. <>p__Sitee.Target(Program.<dynamicMethod>o__SiteContainerd.<>p__Sitee, arg);
C# Matters – dynamic Operation Compilation
dynamic d = 100; d++;
CallSite
![Page 10: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/10.jpg)
C# Matters – Purpose of Callsites
� Callsite обеспечивает динамическую диспетчеризацию методов � Каждый callsite является самообучаемым � DLR сам по себе реализует многоуровневый кэш для типов объектов по отношению к которым производит операцию
� Существует 2 реализации кэша: для Iron-языков и C# � Но обо всем по порядку J
![Page 11: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/11.jpg)
C# Matters - Semantics
� Диспетчеризация методов с использованием callsite сохраняет семантику компилятора C# для разрешения конфликтов при вызове метода, а также выборе перегрузок метода, что означает: � Возможность работы с optional/default параметрами � Поддержку использования implicit conversion operator для переданных параметров
� Специализация generic-методов происходит во время исполнения, а не компиляции
� Использование правил явной, неявной конвертации для числовых типов � Да-да, InvalidCastException имеет место быть
![Page 12: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/12.jpg)
DLR Inside Out - Goals
� “Ручное” использование DLR API дает нам возможность: � Заменить использование Reflection на более быстрый API (сравнение производительности и ответ на вопрос “почему” будет далее)
� Перестать пользоваться Reflection emit для создания оберток и т.п., что дает нам легкоподдерживаемый и читаемый код
� Лучше понять и знать свой инструмент
![Page 13: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/13.jpg)
DLR Inside Out - Infrastructure of dynamic
� Компилятор и среда исполнения используют следующие сборки и пространства имен для инфраструктуры: � System.Dynamic (System.Core.dll) � System.Linq.Expressions (System.Core.dll) � System.Runtime.CompilerServices (mscorlib.dll) � Microsoft.CSharp (Microsoft.CSharp.dll)
![Page 14: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/14.jpg)
object d = 100; object arg = d; if (Program.<dynamicMethod>o__SiteContainerd.<>p__Sitee == null) { Program.<dynamicMethod>o__SiteContainerd.<>p__Sitee = CallSite<Func<CallSite, object, object>>.Create( Binder.UnaryOperation(CSharpBinderFlags.None, ExpressionType.Increment, typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) })); } d = Program.<dynamicMethod>o__SiteContainerd. <>p__Sitee.Target(Program.<dynamicMethod>o__SiteContainerd.<>p__Sitee, arg);
DLR Inside Out – CallSite<T> compile-time
dynamic d = 100; d++;
CallSite
![Page 15: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/15.jpg)
DLR Inside Out – CallSite<T>
namespace System.Runtime.CompilerServices.CallSite { public sealed class CallSite<T> : CallSite where T : class { public T Target; public T Update { get; } public static CallSite<T> Create(CallSiteBinder binder); } }
![Page 16: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/16.jpg)
DLR Inside Out – Callsite’s Life Cycle
Создание узла
Каждый callsite является
статическим полем с “ленивой”
инициализацией
![Page 17: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/17.jpg)
DLR Inside Out – Callsite’s Life Cycle
Создание узла
Генерация кода
Каждый callsite является
статическим полем с “ленивой”
инициализацией
Компилятор C# старается передать DLR максимальное кол-‐во метаданных
![Page 18: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/18.jpg)
DLR Inside Out – Callsite’s Life Cycle
Создание узла
Генерация кода
Вызов
Каждый callsite является
статическим полем с “ленивой”
инициализацией
Компилятор C# старается передать DLR максимальное кол-‐во метаданных
![Page 19: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/19.jpg)
DLR Inside Out – Callsite’s Life Cycle
Создание узла
Генерация кода
Вызов
Каждый callsite является
статическим полем с “ленивой”
инициализацией
Повторная генерация узла при изменении
операндов
Компилятор C# старается передать DLR максимальное кол-‐во метаданных
![Page 20: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/20.jpg)
DLR Inside Out – Callsite generation process
• POCO • COM
CallSite compiler
• C# compiler’s metadata
Metadata analyzer • Reflec[on
Expressions semantic analyzer
• Expression Tree
Code generator • Cache policy
• Delegate
CallSite
![Page 21: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/21.jpg)
DLR Inside Out – PIC
� DLR реализует известную технику PIC, используемую в Google V8, JavaScriptCore, Self VM, Oracle HotSpot VM
� Polymorphic. Узел вызова может иметь несколько состояний, исходя из типов объектов, используемых в динамической операции
� Inline. Жизненный цикл экземпляра класса CallSite проходит именно в месте самого вызова
� Cache. Работа основана на переиспользовании сгенерированного кода благодаря многоуровневому кэшу
![Page 22: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/22.jpg)
DLR Inside Out – Cache
Level 2
Used by all callsites
Adap[ve cache method signature
64-‐128 callsites per opera[on type and
signature
Level 1
Method’s signature-‐based cache
Up to 10 cached callsites
Level 0 Context Type Opera[on type
![Page 23: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/23.jpg)
DLR Inside Out – Monomorphic Performance
0,39 25,85
252,98
2,62 30,13
354,27
0,43 15,38
158,7
2,37 16,46
157,7
0,43 25,96
231,05
0
50
100
150
200
250
300
350
400
Direct Dynamic Reflec[on
Opera[ons performance 1 mln. calls (in ms) (lower – beyer)
Property geyer Property seyer Field geyer Field seyer Method invoke
![Page 24: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/24.jpg)
DLR Inside Out – Polymorphic Performance
0
20
40
60
80
100
120
140
1 2 3 4 5 6 7 8 9 10
ВРЕМ
Я (М
С)
КОЛИЧЕСТВО ТИПОВ
![Page 25: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/25.jpg)
DLR Inside Out – Field/Property getter
CallSite<Func<CallSite, object, object>>.Create( Binder.GetMember(CSharpBinderFlags.None, "PropertyName", typeof (Context), new CSharpArgumentInfo[] { // CSharpArgumentInfo // represents object instance CSharpArgumentInfo.Create( CSharpArgumentInfoFlags.None, null) }) );
![Page 26: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/26.jpg)
DLR Inside Out – Field/Property setter
CallSite<Func<CallSite, object, object, object>>.Create( Binder.SetMember(CSharpBinderFlags.None, "PropertyName", typeof (Context), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create( CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create( CSharpArgumentInfoFlags.None, null) }) );
![Page 27: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/27.jpg)
DLR Inside Out – Indexer getter
CallSite<Func<CallSite, object, object, object>>.Create( Binder.GetIndex(CSharpBinderFlags.None, "PropertyName", typeof (Context), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create( CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create( CSharpArgumentInfoFlags.None, null) }) );
![Page 28: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/28.jpg)
DLR Inside Out – Indexer setter
CallSite<Func<CallSite, object, object, object, object>>.Create( Binder.SetIndex(CSharpBinderFlags.None, "PropertyName", typeof (Context), new CSharpArgumentInfo[] { // three CSharpArgumentInfo // instance[index] = value }) );
![Page 29: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/29.jpg)
DLR Inside Out – Method invocation
CallSite<Action<CallSite, object...[optional args]>>.Create( Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "MethodName", null, typeof (Context), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create( CSharpArgumentInfoFlags.None, null), [optional, args] CSharpArgumentInfo.Create( CSharpArgumentInfoFlags.None, null) }) );
![Page 30: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/30.jpg)
DLR Inside Out – Boxing/Unboxing
� CallSite<Action<CallSite, object...[optional args]>>.Create() может принимать на “вход” как Action<…>, так и Funс<…>
� Generic-параметрами Action<…> и Func<…> могут быть любые типы, которые компилятор сможет вывести еще на этапе компиляции, благодаря чему вместо, например, Action<object, object, object> мы можем получить Action<int, DateTime, string>, что позволит избежать лишней упаковки
� Если не удается вывести типы параметров операции (что весьма маловероятно), то произойдет fallback к Action<object, object, object>, например.
![Page 31: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/31.jpg)
DLR in the wild – C# dynamic Usage Goals
� Использование C# dynamic дает нам возможность: � Взаимодействовать с динамическими языками � Упростить COM-interop � ... � Привнести новые паттерны в мир C# (использовать заменить double dispatch на эффективный multiple dispatch)
� Упростить иерархию классов � Уменьшить императивный код
![Page 32: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/32.jpg)
DLR in the wild –Direct API Usage Goals
� “Ручное” использование DLR API дает нам возможность: � Заменить использование Reflection на более быстрый API � Перестать пользоваться Reflection emit для создания оберток и т.п., что дает нам легкоподдерживаемый и читаемый код
![Page 33: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/33.jpg)
DLR in the wild – Example (Multiple Dispatch pattern with C# dynamic) � Заменим Exception Handling Block библиотеки Enterprise Library на собственный с помощью C# dynamic и паттерна multiple dispatch
� Основными примитивами для обработки исключений в Enterprise Library являются: � ExceptionManager � ExceptionPolicyDefinition � ExceptionPolicyEntry � IExceptionHandler
![Page 34: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/34.jpg)
Enterprise Library – Pros/Cons
� Pros: � Enterprise Library предоставляет приложениям любого типа функционал организации единой схемы обработки исключений. (Примечание: Написание собственного pipeline а-ля ASP.NET & co. требует много усилий и затрат, что не всегда оправдано)
� Cons: � Настройка блока обработки исключений требует относительно большого количества кода для setup
� Количество policy, handler и т.п. сущностей растет пропорционально количеству используемых типов исключений
![Page 35: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/35.jpg)
Enterprise Library – Typical code for exception handling var policies = new List<ExceptionPolicyDefinition>(); var myTestExceptionPolicy = new List<ExceptionPolicyEntry> { { new ExceptionPolicyEntry(typeof (InvalidCastException), PostHandlingAction.NotifyRethrow, new IExceptionHandler[] {new LoggingExceptionHandler(...),}) }, { new ExceptionPolicyEntry(typeof (Exception), PostHandlingAction.NotifyRethrow, new IExceptionHandler[] {new ReplaceHandler(...)}) } }; policies.Add(new ExceptionPolicyDefinition("MyTestExceptionPolicy", myTestExceptionPolicy)); ExceptionManager manager = new ExceptionManager(policies); try { // code to throw exception } catch (Exception e) { manager.HandleException(e, "Exception Policy Name"); }
Really???
![Page 36: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/36.jpg)
Enterprise Library - IExceptionHandler
namespace Microsoft.Practices.EnterpriseLibrary.ExceptionHandling { public interface IExceptionHandler { Exception HandleException(Exception ex, Guid handlingInstanceID); } }
![Page 37: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/37.jpg)
Enterprise Library - ExceptionPolicyDefinition
private ExceptionPolicyEntry FindExceptionPolicyEntry(Type exceptionType)
{
ExceptionPolicyEntry policyEntry = null;
while (exceptionType != typeof(object))
{
policyEntry = this.GetPolicyEntry(exceptionType);
if (policyEntry != null)
{
return policyEntry;
}
exceptionType = exceptionType.BaseType;
}
return policyEntry;
}
![Page 38: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/38.jpg)
Enterprise Library - ExceptionPolicyEntry
public bool Handle(Exception exceptionToHandle)
{
if (exceptionToHandle == null)
{
throw new ArgumentNullException("exceptionToHandle");
}
Guid handlingInstanceID = Guid.NewGuid();
Exception chainException = this.ExecuteHandlerChain(exceptionToHandle, handlingInstanceID);
return this.RethrowRecommended(chainException, exceptionToHandle);
}
![Page 39: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/39.jpg)
Enterprise Library - ExceptionPolicyEntry
private Exception ExecuteHandlerChain(Exception ex, Guid handlingInstanceID) { string name = string.Empty; try { foreach (IExceptionHandler handler in this.handlers) { name = handler.GetType().Name; ex = handler.HandleException(ex, handlingInstanceID); } } catch (Exception exception) { // rest of implementation } return ex; }
![Page 40: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/40.jpg)
DLR in the wild – Own Custom Exception handler interfaces public interface IExceptionHandler { void HandleException<T>(T exception) where T : Exception; } public interface IExceptionHandler<T> where T : Exception { void Handle(T exception); }
![Page 41: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/41.jpg)
DLR in the wild – Own Custom Exception handler implementation public class DefaultExceptionHandler : IExceptionHandler, IExceptionHandler<Exception> { public void HandleException<T>(T exception) where T : Exception { var handler = this as IExceptionHandler<T>; if (handler != null) handler.Handle(exception); else this.Handle(exception as dynamic); } public void Handle(Exception exception) { OnFallback(exception); } protected virtual void OnFallback(Exception exception) { // rest of implementation } }
public class FileSystemExceptionHandler : DefaultExceptionHandler, IExceptionHandler<IOException>, IExceptionHandler<FileNotFoundException> { public void Handle(IOException exception) { // rest of implementation } }
![Page 42: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/42.jpg)
DLR in the wild – Custom Exception handler usage IExceptionHandler defaultHandler = new FileSystemExceptionHandler();
defaultHandler.HandleException(new IOException()); // Handle(IOException) overload
defaultHandler.HandleException(new FileNotFoundException()); // Handle(IOException) overload
defaultHandler.HandleException(new FormatException()); // Handle(Exception) => OnFallback
![Page 43: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/43.jpg)
DLR in the wild – Example (Reflection method invoke vs CallSite API) � Сравним возможности вызова метода с помощью Reflection и с помощью CallSite API � static-методов � instance-методов � Создание делегатов на методы � Применим частичное применение функции (без тавтологии никак J)
![Page 44: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/44.jpg)
DLR in the wild – Delegate using Reflection (Static methods) public static T CreateStaticMethodDelegate<T>(string methodName) where T : class
{
MethodInfo targetMethodInfo = typeof(Calc).GetMethod(methodName,
BindingFlags.Static | BindingFlags.Public,
null,
GetTypeParameters(typeof(T)),
null);
T target = (T) (object) Delegate.CreateDelegate(typeof(T), targetMethodInfo);
return target;
}
private static Type[] GetTypeParameters(Type delegateType) { return delegateType.GetMethod("Invoke") .GetParameters() .Select(x => x.ParameterType) .ToArray(); }
![Page 45: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/45.jpg)
DLR in the wild – CallSite Delegate (Static methods) public static CallSite<T> CreateDynamicStaticMethodDelegate<T>(string methodName) where T : class
{
return CallSite<T>.Create(Binder.InvokeMember(CSharpBinderFlags.None,
methodName,
null,
typeof(Program),
GetCSharpArgumentInfos(typeof(T), true)));
}
![Page 46: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/46.jpg)
DLR in the wild – Reflection vs. CallSite Usage (Static methods) class Program { static void Main(string[] args) { Func<int, int, int> addDelegate = CreateStaticMethodDelegate<Func<int, int, int>>("Sum"); Console.WriteLine("Static delegate: {0}", addDelegate(2, 2)); var addCallSite = CreateDynamicStaticMethodDelegate<Func<CallSite, object, int, int, object>>("Sum"); Console.WriteLine("Static callsite: {0}", addCallSite.Target(addCallSite, typeof(Calc), 4, 4)); addDelegate = (a, b) => (int) addCallSite.Target(addCallSite, typeof (Calc), a, b); Console.WriteLine("Partial applied delegate with callsite: {0}", addDelegate(5, 5)); // Static delegate: 4 // Static callsite: 8 // Partial applied delegate with callsite: 10 } }
![Page 47: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/47.jpg)
DLR in the wild – Delegate using Reflection (Instance methods) public static T CreateInstanceMethodDelegate<T>(string methodName, object instance) where T : class
{
MethodInfo targetMethodInfo = typeof(Calc).GetMethod(methodName,
BindingFlags.Instance | BindingFlags.Public,
null,
GetTypeParameters(typeof (T)),
null);
T target = (T)(object)Delegate.CreateDelegate(typeof(T), instance, targetMethodInfo);
return target;
}
private static Type[] GetTypeParameters(Type delegateType) { return delegateType.GetMethod("Invoke") .GetParameters() .Select(x => x.ParameterType) .ToArray(); }
![Page 48: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/48.jpg)
DLR in the wild – CallSite Delegate (Instance methods) public static CallSite<T> CreateDynamicInstanceMethodDelegate<T>(string methodName) where T : class
{
return CallSite<T>.Create(Binder.InvokeMember(CSharpBinderFlags.None,
methodName,
null,
typeof (Program),
GetCSharpArgumentInfos(typeof (T), false)));
}
![Page 49: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/49.jpg)
DLR in the wild – Reflection vs. CallSite Usage (Instance methods) class Program { static void Main(string[] args) { var calc = new Calc(); Func<int, int, int> addDelegate = CreateInstanceMethodDelegate<Func<int, int, int>>("Add", calc); Console.WriteLine("Delegate: {0}", addDelegate(1, 1)); var addCallSite = CreateDynamicInstanceMethodDelegate<Func<CallSite, object, int, int, object>>("Add"); Console.WriteLine("CallSite: {0}", addCallSite.Target(addCallSite, calc, 3, 3)); // OR MethodInfo addMethodInfo = typeof (Calc).GetMethod("Add", BindingFlags.Instance | BindingFlags.Public, null, new Type[] {typeof (int), typeof (int)}, null); Console.WriteLine("Reflection: {0}", addMethodInfo.Invoke(calc, new object[] {1, 1})); // Delegate: 2 // CallSite: 6 // Reflection: 2 } }
![Page 50: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/50.jpg)
DLR in the wild – Reflection vs. CallSite
� Создание делегатов через Reflection для instance-методов неэффективно, т.к. “захватывает” экземпляр объекта
� Reflection и CallSite предоставляют схожие возможности для делегатов статичных методов
![Page 51: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/51.jpg)
Infinite loop
public class LambdaInstance<T> : LambdaInstance<T, T> { } public class LambdaInstance<T, TPluginType> : ExpressedInstance<LambdaInstance<T, TPluginType>, T, TPluginType> { } public abstract class ExpressedInstance<T> { } public abstract class ExpressedInstance<T, TReturned, TPluginType> : ExpressedInstance<T> { }
![Page 52: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/52.jpg)
Infinite loop
class Program { private static LambdaInstance<object> ShouldThrowException(object argument) { throw new NotImplementedException(); } static void Main(string[] args) { // will be an exception thrown? ShouldThrowException((dynamic)new object()); } }
![Page 53: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/53.jpg)
Infinite loop
class Program { private static LambdaInstance<object> ShouldThrowException(object argument) { throw new NotImplementedException(); } static void Main(string[] args) { // will never end ShouldThrowException((dynamic)new object()); } }
![Page 54: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/54.jpg)
Infinite loop
public class LambdaInstance<T> : LambdaInstance<T, T> { } public class LambdaInstance<T, TPluginType> : ExpressedInstance<LambdaInstance<T, TPluginType>, T, TPluginType> { } public abstract class ExpressedInstance<T> { } public abstract class ExpressedInstance<T, TReturned, TPluginType> : ExpressedInstance<T> { }
![Page 55: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/55.jpg)
Infinite loop
public class LambdaInstance<T> : LambdaInstance<T, T> { } public class LambdaInstance<T, TPluginType> : ExpressedInstance<LambdaInstance<T, TPluginType>, T, TPluginType> { } public abstract class ExpressedInstance<T> { } public abstract class ExpressedInstance<T, TReturned, TPluginType> : ExpressedInstance<T> { }
![Page 56: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/56.jpg)
DLR - Summary
ü Динамизм для .NET ü Эффективный API - быстрее чем Reflection
ü Приемлемая и достижимая производительность ü Без затрат на инфраструктуру ü Легкоподдерживаемый код
ü Новые паттерны для C# ü Mutiple dispatch (“скажем пока” double dispatch, boilerplate-коду и большой иерархии классов)
ü It’s cool J
![Page 57: Эффективное использование Dynamic Language …public.jugru.org/dotnext/2014/moscow/simonyan.pdfDLR Inside Out ! ... На конференции MIX’07 показывается](https://reader031.vdocuments.net/reader031/viewer/2022020108/5b1ed08c7f8b9a853a8bf82d/html5/thumbnails/57.jpg)
Спасибо! Q&A