Не так давно закончил еще один интересный компонент из списка iOS :)
Данный компонент предназначен для прокрутки длинных списков. "Прибить" можно любые данные и описать их с помощью соответствующих шаблонов. Компонент еще "сырой", есть ошибки, поэтому используйте на свой страх и риск.
Пример с двумя вариантами использования ниже.
понедельник, 7 февраля 2011 г.
iOS Silverlight ListControl
понедельник, 27 декабря 2010 г.
iOS Silverlight theme
Стиль iOS очень продуман и очень не плох. Немного подумав, решил реализовать наиболее интересные контролы этой операционной системы в Silverlight. Ниже представлен “Переключатель” в стиле IPhone.
Новые компоненты буду выкладывать по мере реализации.
пятница, 17 декабря 2010 г.
Autofac extensions for PRISM 4
Prism это набор практик , для более простого проектирование богатых, гибких и легких в обслуживании Windows Presentation Foundation (WPF), десктоп приложений, Silverlight Rich Internet Applications (RIA), и Windows 7 Phone приложений. Использование паттернов, воплощают важные архитектурные принципы дизайна, такие как разделение ответственности и слабую связь. Prism позволяет проектировать и строить приложения с использованием слабо связанных компонентов, которые могут развиваться самостоятельно, но которые могут быть легко интегрированы. Такой тип приложений известен как «Модульные приложения».
Последняя версия Prism направленна на Microsoft. NET Framework 4.0 и Silverlight 4 и включает в себя новый принцип реализации модели Model-View-ViewModel (MVVM) паттерна, навигации и Managed Extensibility Framework (MEF).
Подробно.
Autofac
Autofac это IoC контейнер для Microsoft .NET. Он управляет зависимостями между классами таким образом, чтобы приложения оставалось легко изменяемым по мере роста размера и сложности. Это достигается путем обработки обычных классов в виде компонентов.
Последняя версия (2.3) распространяется в виде одной dll’ки размером около 100KB.
Подробно.
Enable Autofac in PRISM
Контейнер Инъекции Зависимостей (Dependency injection containers), дальше просто "контейнер" используются для удовлетворения зависимостей между компонентами; удовлетворение таких зависимостей, как правило, предполагает регистрацию и разрешение компонентов. Из коробки призм обеспечивает поддержку Unity контейнер и Mef, но он является независимым от конкретной реализации контейнера. Поскольку библиотека получает доступ к контейнеру через интерфейс IServiceLocator, он может быть заменен. Для этого, ваш контейнер должен реализовать интерфейс IServiceLocator. Обычно, если вы заменяете контейнер, вы должны также предоставить собственный загрузчик приложения (Bootstrapper) который зависит от реализации контейнера. Какой контейнер использовать – дело личных предпочтений. Я предпочитаю использовать Autofac, поэтому для того чтобы связать его и Prism, необходимо написать собственную реализацию Bootstrapper и IServiceLocator.
Prism очень гибок и расширяем, что позволяет его «заточить» под решение конкретной задачи. При этом архитектура приложения будет «правильной», т.е. готова к изменениям на любом уровне и без последствий (ну или с минимальными). Что еще не маловажно, Prism помогает писать тестируемые приложения с помощью UnitTest’ов.
AutofacBootstrapper
AutofacBootstrapper – реализация абстрактного класса Bootstrapper. Данный класс обеспечивает последовательность начальной загрузки приложения, и регистрирует необходимые компоненты в контейнере Autofac. Реализация ключевых методов класса AutofacBootstrapper выглядит сл. образом:
public abstract class AutofacBootstrapper : Bootstrapper
{
protected virtual IContainer CreateContainer()
{
return ConfigureContainer().Build();
}
protected virtual ContainerBuilder ConfigureContainer()
{
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterInstance(Logger);
containerBuilder.RegisterInstance(ModuleCatalog);
containerBuilder.RegisterSource(new ResolveAnythingRegistrationSource());
if (_useDefaultConfiguration)
{
containerBuilder.Register(x => new AutofacServiceLocatorAdapter(Container))
.As<IServiceLocator>().SingleInstance();
containerBuilder.RegisterType<ModuleInitializer>()
.As<IModuleInitializer>().SingleInstance();
containerBuilder.RegisterType<ModuleManager>().
As<IModuleManager>().SingleInstance();
containerBuilder.RegisterType<EventAggregator>()
.As<IEventAggregator>().SingleInstance();
containerBuilder.RegisterModule(new RegionInitializerModule());
containerBuilder.RegisterModule(new RegionAdapterInitializerModule());
}
return containerBuilder;
}
public override void Run(bool runWithDefaultConfiguration)
{
//run workflow
}
}
Метод “ConfigureContainer” конфигурирует контейнер и возвращает объект, «ContainerBuilder» который, после операции “Build” превратится в рабочий контейнер. В обязательном порядке, контейнер регистрируются “Logger” и “ModuleCatalog”. В контейнер они регистрируются как созданные и сконфигурированные объекты, потому при инъекциях, не будут создаваться новые, а будут использоваться те, что использовались при регистрации. Если приложение использует конфигурацию по умолчанию, в контейнер регистрируются следующие компоненты:
• AutofacServiceLocatorAdapter - адаптер контейнера, для абстракции от конкретной реализации контейнера
• ModuleInitializer – компонент, который создает экземпляр загружаемого модуля и инициализирует его.
• ModuleManager – компонент, который производит загрузку удаленного модуля и зависимостей. После загрузки, модуль инициализируется при помощи компонента “ModuleInitializer”.
• EventAggregator – компонент, который реализует одноименный паттерн.
• RegionInitializerModule – класс, который производит настройку компонентов для работы с регионами.
Также в контейнер регистрируется компонент “ResolveAnythingRegistrationSource”, который расширяет возможности Autofac способностью создавать типы не зарегистрированые в нем непосредственно. Это необходимо для создания экземпляров модулей, которые описаны с помощью структуры «ModuleInfo», которая обеспечивает позднее связывание.
Это метод необходимо перегрузить для регистрации собственных компонентов. Ниже представлен пример из кода “Quickstarts- Modularity”:
protected override ContainerBuilder ConfigureContainer()
{
var containerBuilder = base.ConfigureContainer();
containerBuilder.RegisterType()
.As().SingleInstance();
containerBuilder.RegisterInstance(callbackLogger);
containerBuilder.RegisterType();
return containerBuilder;
}
Метод «CreateContainer» создает контейнер из сконфигурированного «СontainerBuilder». Практическт во всех случаях его не нужно переопределять.Метод «Run» запускает процесс инициализации приложения в строго определенной последовательности.
![]() |
| Последовательность инициализиции компонентов |
Данную последовательность необходимо придерживать при реализации собственного метода.
Параметр, передаваемый в метод, регулирует процесс инициализиции. Если метод был вызван с параметром «True», то нициализация пройдет в обычном режиме и будут проинициализированы и зарегистрированы все необходимые компоненты. Иначе, класс наследник обязывается провести инициализацию этих компонентов самостоятельно. В большинстве случаев нет необходимости менять логику работы этого метода.
AutofacServiceLocatorAdapter
Определяет адаптер для интерфейса IServiceLocator, которые будут использоваться Composite Application библиотеки. Интерфейс IServiceLocator находится в Common Service Locator библиотеке. Эта библиотека с открытым исходным кодом, предназначена для того, чтобы обеспечить абстракцию от IoC (Inversion of Control) контейнера, и сервис локатора (service locator). Цель использования этой библиотеки заключается в привлечении IoC и Service Location без привязки к конкретной реализации. Prism не ссылается или полагаться на конкретный контейнер, но приложение может полагаться на конкретный контейнер. Это означает, что целесообразно для конкретного приложения ссылаться на контейнер, но Prism этого не делает непосредственно.
RegionInitializerModule
Данный модуль использоваться для расслоения на множество связанных с ним компонентов для упрощения настройки и развертывания. Модуль предоставляет преднамеренно ограниченный набор конфигурационных параметров, которые могут изменяться независимо от компонентов, используемых для реализации модуля.
ResolveAnythingRegistrationSource
Данное расширание к Autofac позволяет решить проблему инстенцирования компонентов, которые не были зарегистрированиы в контейнер во время инициализации приложения. Это нужно в момент загрузки и инициализации распределенных модулей приложения. Необходимо отметить, что его использование для инстенцеирование заранее известных компонентов не рекомендуется, так как скорость поиска объектов в контейнере снижается.
Source code
суббота, 9 октября 2010 г.
Rhino Mocks 3.6 for Silverlight
Порт популярной библиотеки (Rhino Mocks 3.6) для создания Mock объектов на платформу Silverlight. Странно что этого не сделал автор библиотеки. Скачать можно здесь.
Update: Core 2.5.1 - September 21st, 2010, исправлены ошибки портирования
пятница, 1 октября 2010 г.
Money sidebar Gadget
Начало.
Money sidebar gadget - программа которая встраивается в боковую панель Windows и отображает текущие курсы валют в Украине с возможностью выбора определенной территории для более точного курса. Также есть возможность отслеживания динамики курсов валют по графику. Программа написана с помошью технологии Silverlight 4, поэтому он должен быть установлен на компьютер. Последнюю версию всегда можно скачать с офф. сайта Microsoft. Gadget можно скачать с Windows Live Gallery или архивом отсюда. Архиватор здесь.
Все данные, гаджет получает с сайта finance.ua.
Money sidebar gadget не работает на 64-битных системах сразу, как этого хотелось бы. Для этого надо поставить в автозагрузку 32-х битную версию Sidebar.
Вариант I:
- Запустить файл "RegSidebar86.reg"(лежит в архиве вместе с gadget, или скачать) для того чтобы поставить в автозагрузку 32-х битную версию Sidebar;
- Сделать Logoff/Logon;
- Добавить гаджет из репозитория.
- Запустить диспетчер задач и убить процесс "sidebar.exe";
- Запустить файл "RegSidebar86.reg"(лежит в архиве вместе с gadget, или скачать) для того чтобы поставить в автозагрузку 32-х битную версию Sidebar;
- Запустить самостоятельно процесс "sidebar" (C:\Program Files (x86)\Windows Sidebar\sidebar.exe)
- Добавить гаджет из репозитория.
О чем речь
![]() |
| Главное окно приложения |
![]() |
| График динамики валюты |
![]() |
| Окно настроек приложения |
![]() |
| Выбор региона |
Должен отметить, что все доступные регионы загружаются с сервера, поэтому если возникают проблемы не сервере, приложение не может их отобразить. При этом будет соответствующее сообщение.
Требования
- Windows 7 :)
- Silverlight 4
- Подключение к интернету :)
Прежде всего необходимо добавить несколько провайдеров, также считать статистику о потребляемом трафике и убрать вкладку Log :).
Затем "причесать" код и открыть его народу.
Решить проблему с работой на платформе х64.
Реализовать способ авто-обновлений.
ЗЫ. Благодарность Димону "З" за тестирование ;).
пятница, 16 июля 2010 г.
Презинтация патерна MVVM
Классная презентация. Почти все расставила по своим местам.
http://houseofbilz.net/codemash/MVVM.ppt
1. Уменьшите или исключите целиком ваш code-behind
2. "Прибивайте" все операции ввода-вывода пользовательского интерфейса к вашей ViewModel
3. Реализуйте INotifyPropertyChanged у вашей ViewModel
4. Разместите поведение View во ViewModel
5. Не размещайте никакого визуального состояния в вашу модель (логично)
6. К модели "прибивайте" только те объекты, которые не содержат никакой UI-специфичной информации (похоже моя идея с локализованными сущностями была забанена)
7. Во время тестирования относитесь ко ViewModel как к настоящему UI (это прокатит только если мы code behind сможем свести к нулю)
8. Избегайте событий. Используйте вместо них команды
суббота, 10 апреля 2010 г.
Entity Framework 4 & Func предикат
В одном и проектов был разработан слой доступа к данным через паттерн Repository и Entity Framework 4 (code only). Интерфейс репозтория выглядел следующим образом:
public interface IRepository<T> where T : class
{
IEnumerable<T> Find(Func<T, bool>; where);
IEnumerable<T> Find(Specification<T> specification);
T Single(Func<T, bool> where);
T Single(Specification<T> specification);
void Delete(T entity);
void Add(T entity);
}
Пока все хорошо, но при реализации первого же метода и анализе запроса к базе данных было обнаружено (
Решение очень протое. Вместо использования предикатов типа:
Func<T, bool>необходимо использовать:
Expression<Func<TEntity, bool>>
Для полноты приведу пример реализации интерфейса репозитория
public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
private readonly IObjectContext _objectContext = null;
private readonly IObjectSet<TEntity> _objectSet = null;
public BaseRepository(IObjectContext objectContext)
{
if (objectContext == null)
throw new ArgumentNullException("objectContext");
_objectContext = objectContext;
_objectSet = _objectContext.CreateObjectSet<TEntity>();
}
protected IQueryable<TEntity> GetQuery()
{
return _objectSet;
}
public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> where)
{
return _objectSet.Where(where);
}
public IEnumerable<TEntity> Find(Specification<TEntity> specification)
{
return specification.SatisfyingElementsFrom(GetQuery());
}
public TEntity Single(Specification<TEntity> specification)
{
return _objectSet.SingleOrDefault(specification.MatchingCriteria);
}
public TEntity Single(Expression<Func<TEntity, bool>> where)
{
return _objectSet.SingleOrDefault(where);
}
public void Delete(TEntity entity)
{
_objectSet.DeleteObject(entity);
}
public void Add(TEntity entity)
{
_objectSet.AddObject(entity);
}
}
Полезные ссылки:







