<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2610681621193384919</id><updated>2012-02-16T00:48:44.867-08:00</updated><category term='c#'/><category term='linq'/><category term='windows mobile 6'/><category term='.net compact'/><category term='active sync'/><category term='patterns'/><category term='wmdc'/><category term='c++0x'/><category term='best practices'/><category term='kaspersky'/><category term='design'/><category term='dotnetconf'/><category term='.net'/><category term='principles'/><category term='стек'/><category term='хак'/><category term='c++'/><category term='asp.net mvc'/><category term='c'/><title type='text'>Блог Родионова Степана</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://rodionovstepan.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://rodionovstepan.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>rodionovstepan</name><uri>http://www.blogger.com/profile/03821423799989719788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://2.bp.blogspot.com/-Qq1YVGMmfw4/TWkWbZPlDHI/AAAAAAAAAAQ/bzlAYbZVUes/s220/avatar.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>8</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2610681621193384919.post-7136565807247265552</id><published>2011-08-13T03:37:00.001-07:00</published><updated>2011-08-13T03:39:20.123-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='best practices'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='principles'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetconf'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net mvc'/><title type='text'>ASP.NET MVC - как построить по-настоящему гибкое веб-приложение</title><content type='html'>&lt;p&gt;Еще раз привет всем!&lt;/p&gt; &lt;p&gt;В марте 2011 года на конференции со мной выступал архитектор компании &lt;a href="http://www.indycode.ru"&gt;IndyCode&lt;/a&gt; – &lt;a href="http://indycode.ru/People/AlexanderZaytsev"&gt;Саша Зайцев&lt;/a&gt;, – он рассказал о своем опыте разработки приложений на платформе ASP.NET MVC Framework. &lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;p&gt;В этом очень полезном докладе освещаются основные проблемы, которые могут встать перед разработчиками/архитекторами, которые также выбрали эту платформу для разработки.&lt;/p&gt; &lt;p&gt;Из доклада вы узнаете разнообразные правила, принципы, практики, которые позволят вам разрабатывать гибкие ASP.NET MVC приложения. Каждая проблема представлена примером, предпосылкой к этой проблеме, а также обязательно решением этой проблемы.&lt;/p&gt; &lt;p&gt;В общем, обязательно к просмотру.&lt;/p&gt;&lt;iframe height="280" src="http://player.vimeo.com/video/22080198?title=0&amp;amp;byline=0&amp;amp;portrait=0" frameborder="0" width="400"&gt;&lt;/iframe&gt; &lt;p&gt;&lt;a href="http://vimeo.com/22080198"&gt;ASP.NET MVC - как построить по-настоящему гибкое веб-приложение&lt;/a&gt; from &lt;a href="http://vimeo.com/user3200582"&gt;Alexander Byndyu&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Всем мир!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2610681621193384919-7136565807247265552?l=rodionovstepan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rodionovstepan.blogspot.com/feeds/7136565807247265552/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://rodionovstepan.blogspot.com/2011/08/aspnet-mvc.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/7136565807247265552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/7136565807247265552'/><link rel='alternate' type='text/html' href='http://rodionovstepan.blogspot.com/2011/08/aspnet-mvc.html' title='ASP.NET MVC - как построить по-настоящему гибкое веб-приложение'/><author><name>rodionovstepan</name><uri>http://www.blogger.com/profile/03821423799989719788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://2.bp.blogspot.com/-Qq1YVGMmfw4/TWkWbZPlDHI/AAAAAAAAAAQ/bzlAYbZVUes/s220/avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2610681621193384919.post-8751640022194204431</id><published>2011-08-13T03:27:00.001-07:00</published><updated>2011-08-13T03:27:30.941-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='best practices'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='principles'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnetconf'/><title type='text'>Мой доклад на конференции .NETconf</title><content type='html'>&lt;p&gt;Привет!&lt;/p&gt; &lt;p&gt;В марте 2011 года я выступал на конференции .NET разработчиков .NETconf (&lt;a href="http://www.dotnetconf.ru"&gt;www.dotnetconf.ru&lt;/a&gt;). Основное направление конференции – это обсуждение передовых практик разработки программного обеспечения.&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;p&gt;Мой доклад назывался “Прагматичный подход к разработке гибких программных систем”. Я попытался включить в доклад много разного материала, о чем сейчас жалею, потому что в итоге очень важные вещи не успел рассказать. В итоге из доклада было выдернуто все о прагматичном подходе к разработке ПО. В общем-то, по-хорошему, из доклада нужно было сделать 2-3 доклада. Тогда эффект был бы намного лучше.&lt;/p&gt; &lt;p&gt;Все желающие могут посмотреть мой доклад сейчас.&lt;/p&gt;&lt;iframe height="265" src="http://player.vimeo.com/video/22064935?title=0&amp;amp;byline=0&amp;amp;portrait=0" frameborder="0" width="400"&gt;&lt;/iframe&gt; &lt;p&gt;&lt;a href="http://vimeo.com/22064935"&gt;Прагматичный подход к разработке гибких программных систем&lt;/a&gt; from &lt;a href="http://vimeo.com/user3200582"&gt;Alexander Byndyu&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Будьте здоровы!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2610681621193384919-8751640022194204431?l=rodionovstepan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rodionovstepan.blogspot.com/feeds/8751640022194204431/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://rodionovstepan.blogspot.com/2011/08/netconf.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/8751640022194204431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/8751640022194204431'/><link rel='alternate' type='text/html' href='http://rodionovstepan.blogspot.com/2011/08/netconf.html' title='Мой доклад на конференции .NETconf'/><author><name>rodionovstepan</name><uri>http://www.blogger.com/profile/03821423799989719788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://2.bp.blogspot.com/-Qq1YVGMmfw4/TWkWbZPlDHI/AAAAAAAAAAQ/bzlAYbZVUes/s220/avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2610681621193384919.post-3667130000226359400</id><published>2011-08-12T10:01:00.001-07:00</published><updated>2011-08-12T10:19:22.464-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++0x'/><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Linq to C++0x</title><content type='html'>&lt;p&gt;Привет!&lt;/p&gt; &lt;p&gt;В C# (начиная с .NET 3.5) есть такая очень интересная вещь – &lt;a href="http://ru.wikipedia.org/wiki/Language_Integrated_Query"&gt;Linq&lt;/a&gt; – проект Microsoft по добавлению синтаксиса языка запросов, напоминающего SQL. Ну, в общем, все знают :)&lt;/p&gt; &lt;p&gt;Я тут решил написать что-то подобное для C++, но перед этим решил поискать в сети что-то готовое. Как оказалось, такое решение уже есть.&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;p&gt;Чувак Daniel Earwicker написал очень крутую штуку: &lt;a href="http://smellegantcode.wordpress.com/2009/05/22/vc16-has-decltype-in-beta-1-so-linq-to-c0x-looks-a-little-nicer/"&gt;http://smellegantcode.wordpress.com/2009/05/22/vc16-has-decltype-in-beta-1-so-linq-to-c0x-looks-a-little-nicer/&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Естественно, этот код будет работать только на новом стандарте C++, т.е. C++0x, т.к. там используются всякие плюшки из этого стандарта.&lt;/p&gt; &lt;p&gt;Всем успехов!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2610681621193384919-3667130000226359400?l=rodionovstepan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rodionovstepan.blogspot.com/feeds/3667130000226359400/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://rodionovstepan.blogspot.com/2011/08/linq-to-c0x.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/3667130000226359400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/3667130000226359400'/><link rel='alternate' type='text/html' href='http://rodionovstepan.blogspot.com/2011/08/linq-to-c0x.html' title='Linq to C++0x'/><author><name>rodionovstepan</name><uri>http://www.blogger.com/profile/03821423799989719788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://2.bp.blogspot.com/-Qq1YVGMmfw4/TWkWbZPlDHI/AAAAAAAAAAQ/bzlAYbZVUes/s220/avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2610681621193384919.post-1398903849658668155</id><published>2011-08-09T09:55:00.001-07:00</published><updated>2011-08-09T09:56:01.740-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Lazy evaluation в IEnumerable</title><content type='html'>&lt;p&gt;Снова всем привет!&lt;/p&gt; &lt;p&gt;Сегодня я бы хотел поговорить о Lazy evaluation (ленивые вычисления), а точнее об этой особенности в IEnumerable. Этот очень удобный интерфейс применяется повсеместно, но не всегда при этом разработчик понимает тонкости его работы. С этим могут быть связаны разные проблемы: лишние вычисления, неверные результаты и пр. В этой статье мне хотелось бы пролить свет на некоторые возможные проблемы использования IEnumerable, чтобы избежать плачевных последствий.&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;p&gt;В основном, проблемы возникают из-за того, что разработчик четко не понимает различий между IEnumerable, Array, List и т.д. У всех этих контейнеров разная природа. Например, для того, чтобы работать с Array мы должны четко указать какого размера мы хотим выделять память, и работаем уже с конкретными ячейками памяти, к которым в любой момент времени можем обратиться. List, хоть и обладаем динамичным размером, внутри реализован через тот же Array, просто когда происходит переполнение, память перераспределяется. И так же в любой момент можно непосредственно обратиться к объекту.&lt;/p&gt; &lt;p&gt;С IEnumerable ситуация совсем другая. Объявление этого интерфейса:&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;public interface IEnumerable&amp;lt;out T&amp;gt; : IEnumerable&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new IEnumerator&amp;lt;T&amp;gt; GetEnumerator();&lt;br&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;Единственный метод GetEnumerator() возвращает перечислитель, интерфейс которого объявлен как:&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;public interface IEnumerator&amp;lt;out T&amp;gt; : IDisposable, IEnumerator&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new T Current { get; }&lt;br&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;Здесь мы видим свойство Current, т.е. текущий элемент в коллекции. Это generic-определение перечислителя, а есть просто IEnumerator:&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;public interface IEnumerator&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; object Current { get; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool MoveNext();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void Reset();&lt;br&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;br&gt;Как видно из определений IEnumerable - это просто фабрика для создания перечислителей (IEnumerator). В свою очередь перечислитель просто поддерживает механизм, с помощью которого можно получить какой-то текущий элемент, перейти к следующему или сбросить результат. Он только должен знать как вычислить следующий элемент или начать процесс заново.&lt;br&gt;Поэтому существование самой коллекции вовсе не обязательно! Вычисляется текущий элемент в методе MoveNext(), затем он возвращает сигнал о том, что можно еще продолжить процесс или его нужно прекратить.&lt;/p&gt; &lt;p&gt;Перейдем к примерам.&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;class Term&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Term(string name, int code)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name = name;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Code = code;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public readonly int Code;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Name;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string ToString()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return string.Format("{0} [{1}]", Name, Code);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;class Thrower&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IEnumerable&amp;lt;Term&amp;gt; ThrowTerms()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; 10; ++i)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return new Term("Name_" + i, i);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;class Program&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void Main()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerable&amp;lt;Term&amp;gt; terms = new Thrower().ThrowTerms();&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var term in terms.Where(x =&amp;gt; x.Code % 2 == 0))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; term.Name = "Caught";&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var term in terms)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(term);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;/font&gt;&lt;br&gt;&lt;br&gt;Запустите этот код. От него мы ожидаем, что у всех Term'ов с четным кодом имя будет "Caught", соответственно, это мы хотим увидеть на экране. Ан нет! На самом деле на экран будет выведено следующее:&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;Name_0 [0]&lt;br&gt;Name_1 [1]&lt;br&gt;Name_2 [2]&lt;br&gt;Name_3 [3]&lt;br&gt;Name_4 [4]&lt;br&gt;Name_5 [5]&lt;br&gt;Name_6 [6]&lt;br&gt;Name_7 [7]&lt;br&gt;Name_8 [8]&lt;br&gt;Name_9 [9]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&lt;/font&gt;&lt;br&gt;Давайте разбираться почему так получилось. На самом деле никакой коллекции объектов не было создано! IEnumerable&amp;lt;Term&amp;gt; terms не содержит в себе никакой коллекции! Сейчас станет понятно почему так получается. Начнем с разбора метода ThrowTerms().&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;for (int i = 0; i &amp;lt; 10; ++i)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return new Term("Name_" + i, i);&lt;/font&gt;&lt;/p&gt; &lt;p&gt;На первый взгляд кажется, что все эти 10 Term'ов будут сложены в какую-то промежуточную коллекцию, а потом одним return'ом она будет возвращена. Но это только на первый взгляд. На самом деле все по-другому! Компилятор создает вложенный в Thrower класс, который реализует интерфейсы IEnumerable&amp;lt;Term&amp;gt; и IEnumerator&amp;lt;Term&amp;gt;, а в методе ThrowTerms() возвращается новый экземпляр этого класса. А сам класс выглядит примерно так:&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class Thower__d0 : IEnumerable&amp;lt;Term&amp;gt;, IEnumerator&amp;lt;Term&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private readonly int _count;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private int _index = 0;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Thower__d0(int count)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _count = count;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IEnumerator&amp;lt;Term&amp;gt; GetEnumerator()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerator IEnumerable.GetEnumerator()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return GetEnumerator();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Dispose()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool MoveNext()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!(_index &amp;lt; _count))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Current = new Term("Name_" + _index, _index);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ++_index;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Reset()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Current = null;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Term Current&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get; private set; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; object IEnumerator.Current&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return Current; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;А метод ThrowTerms() преобразуется в:&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;public IEnumerable&amp;lt;Term&amp;gt; ThrowTerms()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new Thower__d0(10);&lt;br&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;br&gt;Вы можете воспользоваться IL Dasm чтобы посмотреть на скомпилированный код и увидеть все тонкости. Там много интересного :)&lt;/p&gt; &lt;p&gt;Теперь, я думаю, должно стать понятнее почему наши ожидания не совпали с действительностью. Просто на каждой итерации цикла создавался новый экземляр Term'а, который потом просто терялся. Во втором foreach по terms метод ThrowTerms() вызывается второй раз! Получается, что создается новый перечислитель, который просто создает новые экземпляры Term'ов. Это совершенно не заметно, если не знать того, о чем написано в этой статье. И это может иметь неприятные последствия. Например, что было бы если в методе ThrowTerms() было обращение к базе данных или файловой системе? Да-да-да, вместо одного обращения, как мы предполагали, будет два! Очевидно, это может очень навредить производительности, либо привести к неверным результатам!&lt;/p&gt; &lt;p&gt;Ну а как же решить проблему и сделать так, чтобы наши ожидания совпали с реальностью? Достаточно изменить вызов&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;IEnumerable&amp;lt;Term&amp;gt; terms = new Thrower().ThrowTerms();&lt;/font&gt;&lt;/p&gt; &lt;p&gt;на&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;IEnumerable&amp;lt;Term&amp;gt; terms = new Thrower().ThrowTerms().ToList();&lt;/font&gt;&lt;/p&gt; &lt;p&gt;Вызовом ToList() мы инициируем немедленное создание списка, при этом все Term'ы размещаются в массиве внутри List. После этого мы можем обращаться к любому Term'у и что-нибудь с ним делать :)&lt;br&gt;Запускаем код на выполнение и видим то, что хотели:&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Consolas"&gt;Caught [0]&lt;br&gt;Name_1 [1]&lt;br&gt;Caught [2]&lt;br&gt;Name_3 [3]&lt;br&gt;Caught [4]&lt;br&gt;Name_5 [5]&lt;br&gt;Caught [6]&lt;br&gt;Name_7 [7]&lt;br&gt;Caught [8]&lt;br&gt;Name_9 [9]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;Всем внимательности и удачи!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2610681621193384919-1398903849658668155?l=rodionovstepan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rodionovstepan.blogspot.com/feeds/1398903849658668155/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://rodionovstepan.blogspot.com/2011/08/lazy-evaluation-ienumerable.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/1398903849658668155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/1398903849658668155'/><link rel='alternate' type='text/html' href='http://rodionovstepan.blogspot.com/2011/08/lazy-evaluation-ienumerable.html' title='Lazy evaluation в IEnumerable'/><author><name>rodionovstepan</name><uri>http://www.blogger.com/profile/03821423799989719788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://2.bp.blogspot.com/-Qq1YVGMmfw4/TWkWbZPlDHI/AAAAAAAAAAQ/bzlAYbZVUes/s220/avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2610681621193384919.post-3422120643343474372</id><published>2011-07-19T09:20:00.001-07:00</published><updated>2011-07-19T09:20:06.992-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='best practices'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='principles'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Принцип устойчивых зависимостей (Stable Dependencies Principle)</title><content type='html'>&lt;p align="justify"&gt;Всем привет!&lt;br&gt;Сегодня я расскажу о &lt;strong&gt;принципе устойчивых зависимостей&lt;/strong&gt;, знание которого просто необходимо для грамотного проектирования и распределения ответственностей и зависимостей между компонентами системы.&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;p align="justify"&gt;Дизайн разрабатываемой системы не может постоянно оставаться неизменным. Особенно, если систему приходится сопровождать, то она будет довольно часто подвергаться изменениям. Любая система состоит из компонентов, каждый из компонентов имеет разные связи с другими компонентами. Какие-то части подвергаются частым изменениям, а какие-то гораздо реже (скорее всего, это архитектурные решения). В соответствии с частотой изменений, мы должны грамотно уметь проектировать модули. Компоненты, которые, как мы предполагаем, будут редко изменяться, не должны зависеть от компонентов, которые будут меняться часто.&lt;/p&gt; &lt;p align="center"&gt;Формулировка принципа SDP:&lt;br&gt;&lt;strong&gt;&lt;font size="3"&gt;Зависимости должны быть направлены в сторону устойчивости.&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p align="justify"&gt;Командная разработка – это дело особенное, каждый вносит свою лепту в проект. Бывает, например, так, что вы разработали модуль, который достаточно легко подвергается изменениям, а какой-то другой разработчик из команды может его легко сделать трудноизменяемым, просто понавесив на ваш модуль лишних зависимостей. По сути, &lt;strong&gt;SDP&lt;/strong&gt; говорит, что от модулей, которые изначально спроектированы так, чтобы их легко можно было изменять, не должны зависеть модули, изменение которых затруднено. Это так называемые &lt;em&gt;устойчивые&lt;/em&gt; модули.&lt;/p&gt; &lt;p align="justify"&gt;Поговорим об устойчивости. Как можно объяснить устойчивость? Вот, например, рояль является устойчивым? А человек, стоящий на одной ноге? Мне кажется, что человека, стоящего на одной ноге, гораздо легче опрокинуть, чем рояль. То есть для этого нужно приложить гораздо меньше усилий. Поэтому можно сказать, что человек, стоящий на одной ноге – не является устойчивым, а рояль – устойчив. Таким образом, устойчивость – это что-то вроде меры силы, необходимой для выведения из положения равновесия.&lt;/p&gt; &lt;p align="justify"&gt;Какой компонент системы можно назвать устойчивым? Компонент, в сторону которого направлено много зависимостей, т.к. любое изменение этого компонента требует работы по увязке этих изменений в зависимых компонентах. Рассмотрим примеры.&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-W6LWoYsf718/TiWupBIO5vI/AAAAAAAAADo/FOZ-CrqMVmY/s1600-h/stableComponent%25255B38%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="stableComponent" border="0" alt="stableComponent" src="http://lh3.ggpht.com/-0_TdSX7E-g0/TiWupoKfGiI/AAAAAAAAADs/hKRBI2czVbg/stableComponent_thumb%25255B36%25255D.png?imgmax=800" width="240" height="170"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p align="justify"&gt;Компонент А является устойчивым, т.к. от него зависят три других компонента, он несет за них &lt;em&gt;ответственность&lt;/em&gt;. У этого компонента есть как минимум три причины его не изменять. Также А является &lt;em&gt;независимым&lt;/em&gt;, потому что для его изменения нет внешних стимулов.&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-eLKRwSinqOw/TiWuqXi_MRI/AAAAAAAAADw/bpRKNmini70/s1600-h/unstableComponent%25255B11%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="unstableComponent" border="0" alt="unstableComponent" src="http://lh6.ggpht.com/-WXxAN7n16lI/TiWurCJcljI/AAAAAAAAAD0/J6sWIilElWk/unstableComponent_thumb%25255B9%25255D.png?imgmax=800" width="240" height="170"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p align="justify"&gt;А на этом рисунке обратный пример. Компонент B очень &lt;em&gt;не устойчив&lt;/em&gt;, т.к. существует как минимум три внешних причины для его изменения. От этого компонента ничего не зависит – это компонент &lt;em&gt;неответственный&lt;/em&gt;. &lt;/p&gt; &lt;p align="justify"&gt;Чтобы делать конкретные оценки по поводу устойчивости компонентов, существуют метрики устойчивости, которыми пользуются специализированные утилиты, такие как &lt;a href="http://www.ncover.com/"&gt;NCover&lt;/a&gt;. Формула для вычисления метрики устойчивости одного модуля:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh3.ggpht.com/-aQJCt0um9So/TiWurn2jciI/AAAAAAAAAD4/6afZciCKDKw/s1600-h/CodeCogsEqn%252520%2525281%252529%25255B14%25255D.gif"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="CodeCogsEqn (1)" border="0" alt="CodeCogsEqn (1)" src="http://lh4.ggpht.com/-h6maYSHZg7o/TiWusO3SAXI/AAAAAAAAAD8/LEFGoXQJwyc/CodeCogsEqn%252520%2525281%252529_thumb%25255B12%25255D.gif?imgmax=800" width="139" height="45"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p align="justify"&gt;Здесь M&lt;sub&gt;o &lt;/sub&gt;- это число классов вне данного модуля M, зависящих от классов внутри модуля M, а M&lt;sub&gt;i&lt;/sub&gt; – это число классов внутри данного модуля, зависящих от классов вне модуля M. Значение S(M) изменяется от [0; 1], при этом 0 означает абсолютную неустойчивость модуля, т.е. не существует классов, которые бы зависели от классов внутри модуля, а 1 означает абсолютную устойчивость.&lt;/p&gt; &lt;p align="justify"&gt;Мы узнали, как посчитать метрику устойчивости для компонента и это поможет нам понять удовлетворяет ли набор компонентов принципу &lt;strong&gt;SDP&lt;/strong&gt;. Зависимости должны быть направлены в сторону устойчивости, поэтому метрика устойчивости компонента должна уменьшаться с каждым новым уровнем зависимости. Проще говоря, метрика устойчивости S(M) для какого-либо компонента должна быть меньше, чем метрика устойчивости компонентов, от которых он зависит. Рассмотрим схему компонентов:&lt;/p&gt; &lt;p align="justify"&gt;&lt;a href="http://lh3.ggpht.com/-xdIIFFnokuY/TiWus-A6PqI/AAAAAAAAAEA/_MZafp7RyF8/s1600-h/idealScheme%25255B5%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="idealScheme" border="0" alt="idealScheme" src="http://lh6.ggpht.com/-YH9Z9nQ5AGM/TiWutewLG1I/AAAAAAAAAEE/G6ORodjZJRQ/idealScheme_thumb%25255B3%25255D.png?imgmax=800" width="240" height="146"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p align="justify"&gt;Если вся система состоит из этих трех компонентов, то это идеальная схема. Наверху расположены два &lt;em&gt;неустойчивых&lt;/em&gt; компонента: S(A) = S(B) = 0. От них ничего не зависит, это, скорее всего, какие-то конкретные абстрактных классов, и сами они зависят от компонента C. В свою очередь компонент C является очень &lt;em&gt;устойчивым&lt;/em&gt; (S(C) = 1), это &lt;em&gt;ответственный&lt;/em&gt; компонент.&lt;/p&gt; &lt;p align="justify"&gt;Нарушить эту идеальную схему достаточно просто – можно сделать C, зависимым от какого-нибудь компонента D, который в свою очередь тоже является зависимым от других (возможно, устойчивых) модулей. Такое часто происходит при командной разработке.&lt;/p&gt; &lt;p align="justify"&gt;&lt;strong&gt;Заключение.&lt;/strong&gt; Практически все базовые архитектурные решения (фундамент системы) стоит размещать в устойчивых компонентах (S = 1), а части системы, которые предполагается часто изменять, лучше укладывать в неустойчивые компоненты. Но это не всегда работает. Ведь если высокоуровневый дизайн поместить в устойчивые компоненты, то код будет трудно изменять, получается, что дизайн становится не гибким.&amp;nbsp; Как сделать, чтобы максимально устойчивый компонент оставался гибким? Для этого нужно использовать классы, которые можно расширять без модификации, т.е. &lt;em&gt;абстрактные &lt;/em&gt;(см. принцип открытости/закрытости). Мы плавно подошли к &lt;em&gt;принципу устойчивых абстракций&lt;/em&gt;. Но это в следующей статье.&lt;/p&gt; &lt;p align="justify"&gt;&lt;strong&gt;Ссылки.&lt;/strong&gt; Если вы еще не знакомы, то обязательны для изучения принципы SOLID:&lt;br&gt;&lt;a href="http://blog.byndyu.ru/2009/10/blog-post.html"&gt;Single Responsibility Principle&lt;/a&gt;;&lt;br&gt;&lt;a href="http://blog.byndyu.ru/2009/10/blog-post_14.html"&gt;Open/Closed Principle&lt;/a&gt;;&lt;br&gt;&lt;a href="http://blog.byndyu.ru/2009/10/blog-post_29.html"&gt;Liskov Substitution Principle&lt;/a&gt;;&lt;br&gt;&lt;a href="http://blog.byndyu.ru/2009/11/blog-post_19.html"&gt;Interface Segregation Principle&lt;/a&gt;;&lt;br&gt;&lt;a href="http://blog.byndyu.ru/2009/12/blog-post.html"&gt;Dependency Inversion Principle&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2610681621193384919-3422120643343474372?l=rodionovstepan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rodionovstepan.blogspot.com/feeds/3422120643343474372/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://rodionovstepan.blogspot.com/2011/07/stable-dependencies-principle.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/3422120643343474372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/3422120643343474372'/><link rel='alternate' type='text/html' href='http://rodionovstepan.blogspot.com/2011/07/stable-dependencies-principle.html' title='Принцип устойчивых зависимостей (Stable Dependencies Principle)'/><author><name>rodionovstepan</name><uri>http://www.blogger.com/profile/03821423799989719788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://2.bp.blogspot.com/-Qq1YVGMmfw4/TWkWbZPlDHI/AAAAAAAAAAQ/bzlAYbZVUes/s220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-0_TdSX7E-g0/TiWupoKfGiI/AAAAAAAAADs/hKRBI2czVbg/s72-c/stableComponent_thumb%25255B36%25255D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2610681621193384919.post-7841251874092337523</id><published>2011-07-18T11:05:00.000-07:00</published><updated>2011-07-19T06:47:43.802-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='хак'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><category scheme='http://www.blogger.com/atom/ns#' term='стек'/><title type='text'>Натягиваем стек на C</title><content type='html'>Привет!&lt;br /&gt;&lt;br /&gt;Сейчас речь пойдет об одном очень интересном трюке со стеком, который мы провернем на языке C.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Что произойдет, если выполнить следующий код:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;int main()&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;int local = 21;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;printf("%d", a);&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;return 0;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;На экран будет выведено значение переменной local, т.е. 21. При этом память под нее будет выделена на стеке, и мы сможем использовать ее везде в функции main. А что, если мне хочется получить ее значение вне функции main?&amp;nbsp;Это возможно вообще? Конечно! Ведь память на стеке не освобождается после выхода из функции - память под стек выделяется строго определенного размера. Она просто может быть затёрта другой функцией, а может и не быть затёрта... Этим-то и нужно воспользоваться! Тут главное всё правильно подрасчитать и сделать так, чтобы оптимизатор не порефакторил код, как ему нужно :)&lt;br /&gt;&lt;br /&gt;Я хочу получить примерно вот что:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;char putToStack()&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;// помещаем буфер на стек&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;char buffer[16];&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;// как-то его инициализируем&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;void takeFromStack()&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;// тут буфер накладывается на тот, что&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;// уже лежит на стеке&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;char buffer[16];&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;// ...&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Реализация всей этой затеи выглядит примерно так:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;static int a, b, c, d;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;static char *stor = "rodionov~:";&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;static int storlen = 10;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;char putBufferToStack()&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;char buffer[16];&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;d = storlen;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;for (a = 0; a &amp;lt;= d; ++a)&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;c = stor[a];&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;buffer[a] = c;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return buffer[a];&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;void takeFromStack()&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;char buffer[16];&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;printf(buffer);&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;int main()&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; putBufferToStack();&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; takeFromStack();&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; return 0;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Все эти извращения со статическими глобальными переменными нужны для того, чтобы отвлечь оптимизатор.&lt;br /&gt;&lt;br /&gt;Ну а применить это можно, например, для запутывания кода при дизассемблировании.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2610681621193384919-7841251874092337523?l=rodionovstepan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rodionovstepan.blogspot.com/feeds/7841251874092337523/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://rodionovstepan.blogspot.com/2011/07/c.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/7841251874092337523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/7841251874092337523'/><link rel='alternate' type='text/html' href='http://rodionovstepan.blogspot.com/2011/07/c.html' title='Натягиваем стек на C'/><author><name>rodionovstepan</name><uri>http://www.blogger.com/profile/03821423799989719788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://2.bp.blogspot.com/-Qq1YVGMmfw4/TWkWbZPlDHI/AAAAAAAAAAQ/bzlAYbZVUes/s220/avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2610681621193384919.post-6349741235330187659</id><published>2011-07-18T10:39:00.000-07:00</published><updated>2011-07-18T10:39:27.880-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kaspersky'/><category scheme='http://www.blogger.com/atom/ns#' term='windows mobile 6'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='.net compact'/><title type='text'>Kaspersky Deblocker .NET Compact</title><content type='html'>Всем привет!&lt;br /&gt;&lt;br /&gt;Сегодня, наконец, я представлю вашему вниманию тот самый Deblocker, который уже давно разработал.&lt;br /&gt;Все знают о проблеме СМС-блокировщиков - программ, которые блокируют нормальную работу компьютера, и требуют отправить СМС на дорогой платный номер, чтобы получить код разблокировки.&lt;br /&gt;В одно время эта проблема стояла очень остро, поэтому компания Kaspersky Lab разработала веб-сервис, воспользовавшись которым можно бесплатно получить код разблокировки. Нужно просто ввести короткий номер, на который вас просят отправить СМС и (если есть) ключевое слово. Сервис обрабатывает этот запрос и выдает возможные варианты кодов.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Позже компанией был объявлен конкурс на написание приложения под мобильную платформу, использующего их сервис.&lt;br /&gt;Мне было интересно это попробовать. Тем более, что я увлекаюсь компьютерной безопасность, антивирусным ПО (у меня есть самописные антивирусные утилиты), а также я уже имел опыт разработки под Windows Mobile 6. Но в этот раз, я решил попробовать написать программу на .NET Compact, а не на C++, как обычно :)&lt;br /&gt;&lt;br /&gt;Сам сервис достаточно прост. Он принимает обычный GET-запрос и отдает ответ в формате JSON. Параметры в запросе:&lt;br /&gt;sms - короткий СМС номер, на который вас просят отправить СМС;&lt;br /&gt;keywork - ключевое слово (если есть);&lt;br /&gt;lng - язык ответа.&lt;br /&gt;&lt;br /&gt;Пример запроса: &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;http://dbc-www.kaspersky-labs.com/dbc3/processor.php?sms=3116&amp;amp;keyword=79602760984&amp;amp;lng=en&lt;/span&gt;&lt;br /&gt;Ответ на этот запрос:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;[{"keys":["[text]\u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0438\u0441\u043a \u043a\u043e\u0434\u043e\u0432 \u0434\u0435\u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;\u0414\u043b\u044f \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435\u0441\u044c \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0430\u0448\u0435\u0433\u043e \u0444\u043e\u0440\u0443\u043c\u0430&amp;lt;\/a&amp;gt;.[\/text]","avc0cet&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;[text]\u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438: \u043f\u0435\u0440\u0435\u0434 \u0432\u0432\u043e\u0434\u043e\u043c \u043a\u043e\u0434\u0430 \u0441\u043e\u0442\u0440\u0438\u0442\u0435 \u0438\u0437 \u043f\u043e\u043b\u044f \u0432\u0441\u0435 \u0437\u0432\u0435\u0437\u0434\u043e\u0447\u043a\u0438[\/text]","p1d0r&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;[text]\u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438: \u043f\u0435\u0440\u0435\u0434 \u0432\u0432\u043e\u0434\u043e\u043c \u043a\u043e\u0434\u0430 \u0441\u043e\u0442\u0440\u0438\u0442\u0435 \u0438\u0437 \u043f\u043e\u043b\u044f \u0432\u0441\u0435 \u0437\u0432\u0435\u0437\u0434\u043e\u0447\u043a\u0438, \u0441\u0430\u043c \u043a\u043e\u0434 - p \u0435\u0434\u0438\u043d\u0438\u0446\u0430 d \u043d\u043e\u043b\u044c r[\/text]","s1d0r&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;[text]\u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438: \u043f\u0435\u0440\u0435\u0434 \u0432\u0432\u043e\u0434\u043e\u043c \u043a\u043e\u0434\u0430 \u0441\u043e\u0442\u0440\u0438\u0442\u0435 \u0438\u0437 \u043f\u043e\u043b\u044f \u0432\u0441\u0435 \u0437\u0432\u0435\u0437\u0434\u043e\u0447\u043a\u0438, \u0441\u0430\u043c \u043a\u043e\u0434 - s \u0435\u0434\u0438\u043d\u0438\u0446\u0430 d \u043d\u043e\u043b\u044c r[\/text]"],"urls":["\/screenshots\/trojan-ransom.win32.pornoblocker.[black].[big_warning].png"]},{"keys":["\u0432\u0438\u0441\u043a\u0438","135","963963","159159","\u0448\u043e\u0442","\u0448\u043e\u04422","xswxsw","zaqzaq","edcedc","456456","963852","123123","321321","111000","789789","852852","321654"],"urls":["\/screenshots\/trojan-ransom.win32.gimemo.[pornocodec].png"]},{"keys":["62nr25321","dfghdfgff","uhghgkkgf","dfghdhdfr","dgsdfaefd","dfbsffdfd","rtyebfghj","SFSDFSGGD","dhbdfhbdg","ascerlkhg","fglijswrt","dfgfgfssf","dhgfbfghy","fhbgdhdhh","dgdgdgdgd","ghfdghdfh","ereretryf","rel456789","tyrwfdegd","qwaszxvbh","zxzcddfgs","relby7534","relby1234","123456789","relby1239"],"urls":["\/screenshots\/trojan-ransom.win32.pornocodec.[multi].[black]-2.png"]},{"keys":["[text]\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435&amp;lt;\/a&amp;gt;. \u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443.[\/text]"],"urls":["\/screenshots\/fake_from_site_2.png"]},{"keys":["hernqe"],"urls":["\/screenshots\/trojan-ransom.win32.chameleon.[microsoft_security]-2.png"]},{"keys":["\u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435\u0441\u044c \u043d\u0430\u0448\u0438\u043c \u0444\u043e\u0440\u0443\u043c\u043e\u043c&amp;lt;\/a&amp;gt;"],"urls":["\/screenshots\/trojan-ransom.win32.pornocodec.[white].[illegal_activities].png"]},{"keys":["rably1239","relby1239","dfvgbh123","dfvgbh789"],"urls":["\/screenshots\/trojan-ransom.win32.pornocodec.[multi].[black]-1.png"]},{"keys":["sdgfhdthg","fghfgfdfd"],"urls":["\/screenshots\/trojan-ransom.win32.pornocodec.[white].[2_porno_pics].[censored].png"]},{"keys":["tg4ftd3wtg434"],"urls":["\/screenshots\/trojan-ransom.win32.pornocodec.[black]-0.png"]}]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Как видно, в ответе приходят два раздела: keys и urls. Первый - это непосредственно возможные ключи, а второй содержит ссылки на картинки, на которых изображено окно блокировщика, чтобы можно было однозначно понять, такой же ли у вас блокировщик или нет.&lt;br /&gt;&lt;br /&gt;Передо мной встали две основные задачи: 1) разбор JSON ответа сервиса; и 2) наглядное отображение картинок пользователю.&lt;br /&gt;Помимо всего, желательно было реализовать многоязычность (я сделал 2 языка - рус и англ).&lt;br /&gt;&lt;br /&gt;Приступим к обзору приложения.&lt;br /&gt;Главное окно выглядит как-то так:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-aAkgvgvotjk/TiRsZsmIH0I/AAAAAAAAADQ/axmop5uxjRo/s1600/mainMenu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-aAkgvgvotjk/TiRsZsmIH0I/AAAAAAAAADQ/axmop5uxjRo/s320/mainMenu.png" width="205" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Для того, чтобы перейти в основное меню для получения кодов, нажимаем "Get codes". Попадаем на главное окно:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-hEpVdgruw98/TiRsakfqYcI/AAAAAAAAADY/JUsGamiFZNU/s1600/sendingRequest.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-hEpVdgruw98/TiRsakfqYcI/AAAAAAAAADY/JUsGamiFZNU/s320/sendingRequest.png" width="220" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Для примера введем СМС номер 3116, указав при это ключевое слово all, что означает получение всех кодов для этого номера. При нажатии на кнопке "Get codes", отправляется запрос на сервер. Получаем ответ:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-P0_s-zwsBQs/TiRsaBYQ_JI/AAAAAAAAADU/CciYDQyCHwU/s1600/responseExample.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-P0_s-zwsBQs/TiRsaBYQ_JI/AAAAAAAAADU/CciYDQyCHwU/s320/responseExample.PNG" width="207" /&gt;&lt;/a&gt;&lt;/div&gt;В текстовом окне перечисляются коды и инструкции по их применению. В правом нижнем углу можно увидеть уменьшенное изображение блокировщика. Чтобы просмотреть все виды блокировщиков для данных кодов, можно нажать "View screenshots". Переходим в окно выбора скриншота:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-qDiOVSVd0Pw/TiRsbJaPqMI/AAAAAAAAADc/4Ek8pexTa8M/s1600/viewScreenshots.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-qDiOVSVd0Pw/TiRsbJaPqMI/AAAAAAAAADc/4Ek8pexTa8M/s320/viewScreenshots.PNG" width="202" /&gt;&lt;/a&gt;&lt;/div&gt;Нажав непосредственно на изображении, можно посмотреть скриншот в полный экран вашего устройства. Например, так:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Ndn5vpAW8jo/TiRt1_tVsQI/AAAAAAAAADg/eJLE-uNTZjY/s1600/fullviewScreenshot.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-Ndn5vpAW8jo/TiRt1_tVsQI/AAAAAAAAADg/eJLE-uNTZjY/s320/fullviewScreenshot.PNG" width="208" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;На этом собственно обзор закончен.&lt;br /&gt;&lt;br /&gt;Исходный код приложения:&amp;nbsp;&lt;a href="http://www.getzilla.net/files/1366144/deblocker.zip.html"&gt;deblocker.zip&lt;/a&gt;&lt;br /&gt;Необходим .NET Compact 2.0.&lt;br /&gt;Кстати, т.к. это .NET, то приложение можно запустить и на обычной Windows.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2610681621193384919-6349741235330187659?l=rodionovstepan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rodionovstepan.blogspot.com/feeds/6349741235330187659/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://rodionovstepan.blogspot.com/2011/07/kaspersky-deblocker-net-compact.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/6349741235330187659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/6349741235330187659'/><link rel='alternate' type='text/html' href='http://rodionovstepan.blogspot.com/2011/07/kaspersky-deblocker-net-compact.html' title='Kaspersky Deblocker .NET Compact'/><author><name>rodionovstepan</name><uri>http://www.blogger.com/profile/03821423799989719788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://2.bp.blogspot.com/-Qq1YVGMmfw4/TWkWbZPlDHI/AAAAAAAAAAQ/bzlAYbZVUes/s220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-aAkgvgvotjk/TiRsZsmIH0I/AAAAAAAAADQ/axmop5uxjRo/s72-c/mainMenu.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2610681621193384919.post-186426143118481251</id><published>2011-03-02T10:20:00.000-08:00</published><updated>2011-03-02T10:27:25.266-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='active sync'/><category scheme='http://www.blogger.com/atom/ns#' term='windows mobile 6'/><category scheme='http://www.blogger.com/atom/ns#' term='wmdc'/><title type='text'>Синхронизация эмулятора Windows Mobile 6 c ПК</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Давненько уже думал создать-таки свой блог и вот нашел время для этого. Надеюсь частенько писать сюда что-нибудь интересное :)&lt;br /&gt;&lt;br /&gt;В своем первом посте я расскажу о том, как синхронизировать эмулятор Windows Mobile 6.x с ПК, например, для того чтобы приложения имели возможность работать с Интернетом. Понадобилось мне это для написания приложения, взаимодействующего с сервисом Лаборатории Касперского по получению ключей для разблокировки компьютеров. Это блокировщики, которые просят отправить СМС на определенный номер, чтобы получить код разблокировки.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Для выполнения поставленной задачи мне понадобились следующие средства:&amp;nbsp;&lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=38c46aa8-1dd7-426f-a913-4f370a65a582&amp;amp;displaylang=en"&gt;эмулятор Windows Mobile 6.x&lt;/a&gt;,&amp;nbsp;&lt;a href="http://www.microsoft.com/windowsmobile/ru-ru/downloads/microsoft/device-center-download.mspx"&gt;центр устройств Windows Mobile (WMDC)&lt;/a&gt;&amp;nbsp;ну и Visual Studio 2008. Студия именно 2008, т.к. в 2010 изначально нет поддержки проектов под Windows Mobile 6.x.&lt;br /&gt;&lt;i&gt;Примечание: для Windows XP нужен не WMDC, а ActiveSync.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Ну а теперь по порядку. Сначала настроим WMDC. В разделе параметров подключения мобильного устройства нужно поставить галочку напротив пункта "Разрешить подключения одного из следующих типов", и выставить значение "DMA". Сохраняем настройки.&lt;br /&gt;&lt;br /&gt;Далее запускаем эмулятор WM6 и открываем приложение Device Emulator Manager. В Visual Studio его запустить можно через меню Tools &amp;gt; Device Emulator Manager...&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;Затем из списка эмуляторов нужно выбрать тот, который выполняется в данный момент, открыть контекстное меню и нажать Cradle, это заставит WMDC начать синхронизацию.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh6.googleusercontent.com/-iFBo10yJEvA/TW6GeRH6NKI/AAAAAAAAAA0/m2xG1ZhhcXY/s1600/Cradle.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="https://lh6.googleusercontent.com/-iFBo10yJEvA/TW6GeRH6NKI/AAAAAAAAAA0/m2xG1ZhhcXY/s400/Cradle.png" width="336" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Теперь мы можем увидеть, что устройство синхронизировано!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh6.googleusercontent.com/-9s1OeJ7XQx4/TW6HwMSv12I/AAAAAAAAAA4/vxGdX8-7Om8/s1600/Connected.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="271" src="https://lh6.googleusercontent.com/-9s1OeJ7XQx4/TW6HwMSv12I/AAAAAAAAAA4/vxGdX8-7Om8/s400/Connected.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;Но радоваться рано... :)&lt;br /&gt;&lt;br /&gt;Я когда с этим разбирался думал, что этого уже достаточно для того, чтобы Интернет синхронизировался и на эмулятор, но это было не так. Видимо, я до конца не разобрался в инструкции (если честно, я ее вообще не читал). Поэтому пришлось разбираться дальше.&lt;br /&gt;Чтобы, наконец, Интернет был и на устройстве, нужно в WMDC снова зайти в параметры подключения мобильного устройства и в пункте "Этот компьютер подключается" поставить значение "К Интернету", и сохранить настройки.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh3.googleusercontent.com/-q0NJsqMepWQ/TW6JIm4SH8I/AAAAAAAAAA8/w6HR814P_f0/s1600/ConnectionSettings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="280" src="https://lh3.googleusercontent.com/-q0NJsqMepWQ/TW6JIm4SH8I/AAAAAAAAAA8/w6HR814P_f0/s400/ConnectionSettings.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Все, теперь ваш эмулятор может работать с Интернетом.&lt;br /&gt;Следующий пост я, скорее всего, посвящу описанию того приложения, которое я разрабатывал для взаимодействия с сервисом.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2610681621193384919-186426143118481251?l=rodionovstepan.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rodionovstepan.blogspot.com/feeds/186426143118481251/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://rodionovstepan.blogspot.com/2011/03/windows-mobile-6-c.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/186426143118481251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2610681621193384919/posts/default/186426143118481251'/><link rel='alternate' type='text/html' href='http://rodionovstepan.blogspot.com/2011/03/windows-mobile-6-c.html' title='Синхронизация эмулятора Windows Mobile 6 c ПК'/><author><name>rodionovstepan</name><uri>http://www.blogger.com/profile/03821423799989719788</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://2.bp.blogspot.com/-Qq1YVGMmfw4/TWkWbZPlDHI/AAAAAAAAAAQ/bzlAYbZVUes/s220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/-iFBo10yJEvA/TW6GeRH6NKI/AAAAAAAAAA0/m2xG1ZhhcXY/s72-c/Cradle.png' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
