Пишем код

Заметки о .net разработке

Archive for Ноябрь, 2011

Устранение magic-strings в javascript

without comments

Недавно я озадачился проблемой «магических строк», которые регулярно появляются в яваскрипте.

Допустим, у нас на страничке динамически генерируются блоки вида:

<br />
<span animate_period="10" animate_amplitude="20"></span><br />

И есть javascript-код, который ищет блоки с этими атрибутами и в соответствии со значениями применяет определенную анимацию. В итоге имена атрибутов (magic-strings по сути) дублируются во вьюшках/контроллерах и js-файлах.
Еще одной похожей проблемой становится посылка аякс-запросов к контроллерам:
<br />
$('#mydiv').load("http://mysite.ru/Items/GetItemInfo?id=20");<br />

URL запроса явно грозит нам опечатками и/или ошибками, когда этот адрес изменится.
Если мы пишем яваскрипт-код прямо в html файлах (а не в отдельных подключаемых скрипт-файлах), то можно, конечно, воспользоваться T4MVC и написать что-то вроде:
<br />
$('#mydiv').load("@Url.Action(MVC.Items.GetItemInfo())");<br />

Как раз о таком способе решения проблемы я недавно и писал. Но если js вы всё-таки выносите в отдельные файлы (а делать это надо — для уменьшения дублирования и клиентского кэширования), то проблема так просто не решается.

Столкнувшись с проблемой на довольно-таки большом проекте, в голову пришла мысль воспользоваться всей мощью шаблонов T4 и сгенерировать соответствующие javascript-хэлперы. Всё сложилось удачно (шаблон можно скачать), в результате обработки данного шаблона получается яваскрипт-файл T4MVC-JS.js, который можно легко инклюдить через тег <script> в хтмле, и так как он генерится не в рантайме и для Visual Studio ничем не отличается от обычного яваскрипт-файла, то по объявленным в нем переменным работает интеллисенс, что сокращает вероятность ошибок.
Read the rest of this entry »

Written by Shaddix

Ноябрь 29th, 2011 at 1:39 пп

Светлая сторона property-injection

2 комментария

О плюсах инверсии зависимостей и той гибкости, которую она даёт приложениям сказано очень многое, и я искренне надеюсь, что она повсеместно используется :)
Как известно, существует несколько способов инверсии зависимостей:

  • Constructor-based injection — инъекция через конструктор. Класс объявляет свои зависимости как параметры в конструкторе:
    <br />
        public class MyImageProcessor<br />
        {<br />
            private readonly IScreenshooter _screenshooter;<br />
            private readonly IImageResizer _imageResizer;<br />
            private readonly IImageComparer _imageComparer;</p>
    <p>        public MyImageProcessor(IScreenshooter screenshooter, IImageResizer imageResizer, IImageComparer imageComparer)<br />
            {<br />
                _screenshooter = screenshooter;<br />
                _imageResizer = imageResizer;<br />
                _imageComparer = imageComparer;<br />
            }<br />
        }<br />
    

    Процессор получает сервисы, которые ему нужны для работы через конструктор и в дальнейшем работает с ними.
  • Property-based injection — инъекция через публичные свойства. Свойства в этом случае обычно необходимо украшать атрибутами:
    <br />
        public class MyImageProcessor2<br />
        {<br />
            [Inject]<br />
            public IScreenshooter Screenshooter { get; set; }<br />
            [Inject]<br />
            public IImageResizer ImageResizer { get; set; }<br />
            [Inject]<br />
            public IImageComparer ImageComparer { get; set; }</p>
    <p>        public MyImageProcessor2()<br />
            {<br />
            }<br />
        }

    Выглядит короче, но имеет очевидные минусы — зависимости класса непонятны (легко забыть инициализировать свойства, например, из тестов; при инъекции через конструктор с этим проблем нет), доступ к сервисам «открыт внешнему миру», что также не всегда является желаемым поведением.

Есть еще field-injection, когда инъекция идет не через публичные свойства, а через публичные поля, но этот вариант уже почти официально считается «говнокодом» :)

До недавнего времени в подавляющем большинстве случаев я использовал инъекцию через конструктор, и с трудом представлял причины, по которым можно предпочесть property-injection.
Read the rest of this entry »

Written by Shaddix

Ноябрь 18th, 2011 at 11:05 пп

Posted in .net,IoC