Как я должен ленивый генерировать миниатюру изображения? - PullRequest
0 голосов
/ 13 мая 2009

Для фона у меня есть слой данных и сервисный слой, свободно основанные на модели магазина Роба Конери, и, как и у Роба, многие из моих доменных объектов и объединены LazyList<> и LazyItem<> использовать отложенное выполнение, которое предоставляет Linq2Sql, учитывая, что мои типы Lazy* используют IQueryable<T>, а не , этот потрясающий делегатский подход .

Итак, у меня есть такой граф объектов (в основном, у каждого занятия должна быть фотогалерея множества изображений - миниатюр и полноразмерных фотографий):

latest3Activities[0].Gallery.Images.Inner[1].FullImage

Тип Gallery имеет свойство Images LazyList<PhotoGalleryImage>, поэтому IList<PhotoGalleryImage> из этого LazyList - это Inner, который вы видите. Каждый элемент PhotoGalleryImage имеет свойство FullImage и свойство Thumbnail, оба типа Image.

Идея состоит в том, что полностью загруженная фотография рез хранится в свойстве PhotoGalleryImage.FullImage, и изначально свойство Thumbnail имеет значение Null. Что мне нужно, так это: когда к свойству Thumbnail обращаются в первый раз, если это Null, я хочу, чтобы мой слой Service генерировал Thumb, сохранил его в БД, а затем вернул экземпляр Image что меньше фото. У меня есть весь код для создания миниатюры из полноразмерного изображения, так что здесь вопрос не в этом.

То, что я не могу понять, это как поймать первый доступ к свойству Thumbnail (в контексте моей архитектуры IQueryable<>), а затем сделать так, чтобы уровень обслуживания выполнял изменение размера, а не хранилища (DAL). Я твердо убежден, что сервисный (бизнес) уровень должен отвечать за это функциональное решение, но я не понимаю, как заставить его работать.

В настоящее время я думаю, что сопоставление классов моего домена в репозиториях с классами Linq2Sql было бы хорошим местом для определения этого «первого доступа», на который я ссылаюсь, но я не вижу, как нижний уровень может затем вызвать в слой Service и выполнить сжатие (или даже если это возможно, что он должен ).

Может быть, мой дизайн заставляет меня делать Repos преобразованием. Может быть, я не хочу, чтобы сервисный уровень вообще выполнял эту логику. Возможно, мой дизайн настолько ужасен, что мне вообще не стоит сталкиваться с этим беспорядком.

Пожалуйста, помогите. Все отзывы приветствуются.

Ответы [ 3 ]

2 голосов
/ 13 мая 2009

У меня была очень похожая проблема пару месяцев назад с загруженными изображениями, генерацией миниатюр и вопросом о том, куда должен идти код для генерации миниатюрных изображений. Я тоже действительно чувствовал, что этот код принадлежит служебному слою (не в последнюю очередь потому, что хранилище для файлов изображений и миниатюр было абстрагировано в интерфейс и внедрено через контейнер IOC, и я не хотел, чтобы какая-либо инъекция зависимостей в мой домен слой).

В конце я создал все миниатюры в том месте, где изображение загружается через вызовы на сервисный уровень из контроллера пользовательского интерфейса. Я попытался сгенерировать изображения в доменном слое до этого, хотя. Для этого я использовал шаблон, в соответствии с которым при создании изображения на уровне домена он вызывал событие, подключенное к уровню службы. Затем сервисный уровень передает экземпляр интерфейса хранилища обратно через аргументы событий на уровень домена, чтобы уровень домена мог сохранять изображение. Это было очень свободно основано на некоторых идеях в блоге Уди Даана , с которыми мне приходилось сталкиваться, используя события в доменной модели как способ использования логики на уровне обслуживания. К сожалению, сейчас я не могу найти ссылку на сайт Уди, но она где-то есть. В любом случае, это никогда не казалось правильным - это было похоже на тесную связь через другой маршрут, поэтому я вернулся к созданию миниатюр в момент первой загрузки изображения через сервисный слой. Однако, возможно, в вашем случае вы могли бы использовать идею событий из доменного уровня для вызова логики на сервисном уровне. Я уверен, что в самой идее есть большая ценность, просто она не совсем соответствует тому, что я делал.

2 голосов
/ 13 мая 2009

Смысл ленивого init заключается в том, чтобы отложить выделение ресурсов, так как вы не знаете, когда они вам нужны или нет.

В вашем случае это на самом деле не имеет смысла: как только изображение будет загружено, серверу понадобится миниатюра - пользователь хочет немедленно увидеть новое изображение, верно? Следовательно, отсрочка создания эскиза не имеет положительного ROI.

0 голосов
/ 13 мая 2009

Я предполагаю, что для отображения изображения вам необходим URI изображения, который может быть передан вам с помощью IThumbnailingService, который при необходимости создаст миниатюру и вернет действительный URI, который указывает на сгенерированное изображение.

...