{season} of code

Мои первые попытки использовать Test Driven Development закончились обычными проблемами с доступом к данным. Почти сразу выяснилось, что:

1. Невозможно использовать настоящую базу данных для запуска тестов. Каждый тест не должен зависеть от результатов других тестов. На практике это означает что каждый тест должен выполняться на чистой базе (в худшем случае), или что каждый тест должен быть обернут в транзакцию, с откаткой после выполнения.

2. Невозможно заменить весь код доступа к данным mock-ами. На самом деле, можно попробовать, но это привязывает тесты к конкретной реализации функционала. Вы вынуждены создавать mock для каждого обращения к DAL. Вы так же вынуждены изменять тесты при рефакторинге, что усложняет разработку сопровождение.

Общепринятое решение этих проблем – использование шаблонов Persistence Ignorance (PI) и Repository. Достаточно погуглить “IQueryable Repository”и вы найдете чуть более 9000 упоминаний чего-то вроде:

interface IRepository

{

    IQueryable<T> All<T>();

    void Insert<T>(T entity);

    void Update<T>(T entity);

    void Delete<T>(T entity);

}

…и множество реализаций этого интерфейса поверх LINQ To SQL. Несмотря на разнообразие, практически все они реализуют все один и тот же тип шаблона Repository - “Plain old CLR objectRepository. Это означает, что на базовый шаблон они накладывают довольно сильные ограничения.

Самое серьезное – то, что объекты должны быть “плоскими” в худшем смысле этого слова. Вы не можете заставить POCO Repository загрузить связи между объектами. Вы не можете написать код вроде:

repository.All<Project>()

    .Where(p => p.Tasks.Count > 10);

В мире POCO связей вообще не существует! Одну короткую строчку кода вам придется заменить вот этим:

var projectIds = repository.All<Task>()

    .GroupBy(t => t.ProjectId)

    .Where(gr => gr.Count() > 10)

    .Select(gr => gr.Key)

    .ToList();

 

repository.All<Project>()

    .Where(p => projectIds.Contains(p.Id));

Даже такой простой пример раздувается до двух запросов, с использованием IN. Написав такой мегакод пару раз, я решил что нужно найти способ запихнуть этот запрос назад в одну строчку. И при этом сохранить поддержку Persistence Ignorance.

Осталось придумать лишь еще одну реализацию шаблона Repository, которая:

1. Полностью поддерживает связи (Associations). Она должна поддерживать выполнение кода вроде:

repository.All<Task>()

    .Where(t =>

            t.Project.Customer.Name.StartsWith("a"));

2. Поддерживает загрузку связанных объектов (Deep Load). Она должна уметь загружать одиночные и множественные зависимости по требованию.

// задачи, со свойством Project установленным в  null

repository.All<Task>();

 

// задачи с загруженным свойством Project

repository.All<Task>()

    .LoadWith(t => t.Project);

 

// задачи в будущих проектах

// свойство Project не загружено (null)

repository.All<Task>()

    .Where(t => t.Project.StartDate > DateTime.Today);

3. Поддерживает перехват запросов (Query Interception), для красивых глобальных фильтров

// задачи видимые текущему пользователю

// поведение по умолчанию

repository.All<Task>();

 

// все задачи, без учета прав пользователя

repository.All<Task>()

    .IgnorePermissions();

 

// сообщения со статусом != Deleted

// поведение по умолчанию

repository.All<Message>();

 

// только “удаленные” сообщения

repository.All<Message>()

    .Deleted();

 

// все сообщения

repository.All<Message>()

    .IncludeDeleted();       

4. Позволяет легко переключиться между LINQ To SQL и In-Memory реализациями, одним ключом в конфиге. Изначально ориентирована на использование IoC/DI.

Мы попытались решить эти проблемы и сделать “старые плоские” объекты не настолько плоскими и старыми. Код и примеры выложены на  http://lsda.codeplex.com/. Этот блог будет постепенно расти до полноценной документации :)

Отзывы, пожелания и патчи приветствуются.

50 Responses to “IQueryable Repository – Что дальше?”

  1. build_your_web

    Жаль что вы только начали.
    Как раз ищу подобную библиотеку.

  2. PashaPash

    2build_your_web: начали - понятие осносительное. мы на нем уже штук 5 проектов сдали.
    Попробуй забрать source code с кодеплекса, там есть базовые примеры. Постараюсь до конца недели зарелизить и выложить более полные семплы.

  3. xumix

    а где можно посомтреть конкретные примеры, где видно преимущества Repository?

  4. Борис

    Честно, неплохая новость

  5. Софья

    Вот именно с этой статьи начинаю читать Ваш блог. Плюс один подписчик

  6. Pam

    Lesbian’s World ” It’s Our Time Now

  7. Genete

    Lesbian’s World ” It’s Our Time Now

  8. Софья

    Класс! Очень понравилось

  9. Дарья

    На каком-то сайте я уже читал почти такую же подборку инфы, но все равно спасибо

  10. Анфиса

    Да уж, хорошо написано.

  11. Сусанна

    Очень просто на словах а в деле, многое несоответсвует, не так всё радужно!

  12. Justin Bieber Arrested Video

    Amazing, truly excellent information. Your blog is really awesome. I bookmarked this and will come back once again. . . .

  13. Justin Bieber Arrested Video

    I tried to subscribe to your rss feed, but had a problem adding it to google reader. Could you please check this out.

  14. Марта

    Побольше б таких штук…Beautiful! :-)

  15. Диана

    Автор, отлично. Только не пихайте где только можно рекламу

  16. Юлия

    А Вы не задумывались о том, чтобы параллельно завести еще один блог, на смежную тему? У Вас неплохо получается :)

  17. Лилия

    Классно, вещь полезная!

  18. Александр

    Огромное человеческое спасбо!

  19. eurosportpoker

    A weblog with information very exciting, congratulations to the writer!

  20. Анфиса

    Интернет пишется с большой буквы внутри предложения, если что. И сотые не с точкой, а с запятой. Это по стандарту. А так неплохо все, просто вэри гуд!

  21. Иришка

    Horoshaya infa!

  22. Арсен

    блин, почему так мало хороших блогов осталось? этот вне конкуренции

  23. Валентина

    Побольше б таких штук…Beautiful! :-)

  24. Антонина

    Действительно полезняк! А то сколько не лазишь по нету сплошное бла бла бла. Но не тут, и это радует!

  25. Лидия

    Слушай, аффтар, а ты сам писал или перписывал откуда-то?

  26. Jhonny Peralta Stats

    Thanks for taking the time to share this, I feel strongly about it and love reading more on this topic. If possible, as you gain knowledge, would you mind updating your blog with more information? It is extremely helpful for me.

  27. Jhonny Peralta Stats

    Amazing, truly excellent information. Your blog is really awesome. I bookmarked this and will come back once again. . . .

  28. Анастасия

    Сугубо мое имхо - ты не можешь определиться с выбором. Удачи, подумай над этим.

  29. Кира

    Хороший пост, всегда с удовольствием Вас читаю

  30. chanel handbags

    JJ, do you even know what free-market competition is? “It’s ridiculous to assume liberals don’t believe in free market competition. We believe in free market competition with a level playing field for everyone.” That’s like saying the Lakers and the Cavaliers are too good, so they have to give Lebron and Kobe to the Nets and the T’wolves, so that everyone can “compete” on a “level playing field.”

  31. chanel handbags

    I don’t agree. But still good post.

  32. Арсен

    Полностью с Вами согласна, примерно неделю назад написала про этоже в своем блоге!

  33. Берта

    Прелестно) Хм… забавненько

  34. gadgets kopen

    I don”t think so…

  35. Monroe Snellman

    Also if it does have a chance of working do I have to go google for the needed demo or is it still hosted by Sony?

  36. dell battery

    Useful information, thank you. I’ll be glad to see you on my site.

  37. natural detox marijuana

    I enjoyed reading your post. It’s very engaging and quite useful for me. Wish to get some more information though.

  38. cooking recipes

    I always learn something new, thanks for sharing this article.

  39. Александр

    Я внимательно читал второй абзац и не вкурил суть изложенного

  40. Electronic Cigarette

    Thanks for the read, I will bookmark it and come back later to check out some of your other posts =)

  41. Олег

    Хотелось бы что-то наваять в комментах креативного, но мысль не складывается, так что просто зачОт

  42. онлайн видео

    Да довольно таки прикольно!

  43. property solicitors

    I will visit your blog regularly for some latest post.

  44. wedding pillow

    Only want to say your article is as tonishing. The clearness in your post is simply spectacular and i can take for granted you are an expert on this field. Well with your permission allow me to grab your rss feed to keep up to date with succeeding post. Thanks a million and please keep up the ac complished work.

  45. Газификация

    ТС, не стоит обольщаться.
    PS: А в целом не понятен общий смысл.

  46. women peeing

    Just a fast hello and also to thank you for discussing your tips on this page. I wound up in your weblog right after researching physical fitness associated points on Yahoo… guess I lost track of what I had been performing! Anyway I’ll be back once more in the long term to verify out your blogposts down the road. Thanks!

  47. coffee acidity

    You really make it seem so easy with your presentation but I find this topic to be really something which I think I would never understand. It seems too complicated and very broad for me. I am looking forward for your next post.

  48. ESPY Awards 2010

    I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well. In fact your creative writing abilities has inspired me to start my own BlogEngine blog now. Really the blogging is spreading its wings rapidly. Your write up is a fine example of it.

  49. Lingerie

    Nice site, I just dugg this keep up the good work!. . . . . .

  50. Saving Account

    great thing all of us gots the internetz

Leave a Reply

Proudly powered by WordPress. Theme developed with WordPress Theme Generator.
Copyright © {season} of code. All rights reserved.