Есть ли вещи, на которые стоит обратить внимание при использовании Dependency Injection Framework в asp.net? - PullRequest
0 голосов
/ 31 октября 2009

Как проблемы с потоками? Узкие? Проблемы с памятью?

Ответы [ 3 ]

1 голос
/ 31 октября 2009

Это зависит от того, какие рамки вы нам используете, но в целом я бы сказал нет. Вы должны настроить IoC в одном потоке, а затем все остальные потоки читают из IoC. Если вас беспокоят узкие места или нехватка памяти, вы можете сами справиться, но большинство известных решений также не имеют этих проблем.

EDIT: Я подумал, что обновлю это, чтобы предоставить больше информации и уточнить мой ответ.

Это моя точка зрения, но основными целями контейнера DI являются гибкость и тестируемость. С гибкой точки зрения у вас нет ссылок на конкретные реализации в вашей бизнес-логике. Например, если вам нужна служба планирования в вашей логике без DI или какой-либо фабрики, вам нужно сделать что-то вроде этого:

SchedulingService schedulingService = new SchedulingService();

Но с DI-контейнером или фабрикой вы бы сделали что-то вроде:

ISchedulingService schedulingService = IoC.GetInstance<ISchedulingService>();

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

public UpdateDeployment(ISchedulingServer Scheduler)
{
     _scheduler = Scheduler;
}

, который затем может быть подделан или подделан во время теста. Но в вашей бизнес-логике вы могли бы вызвать перегруженный конструктор по умолчанию для бизнес-объекта, который захватывает зависимость из контейнера DI и затем вызывает этот конструктор выше:

public UpdateDeployment() : this (IoC.GetInstance<ISchedulingService>()) {}

Теперь, учитывая все сказанное, из того, что я сделал, контейнер DI является хеш-таблицей с некоторой логикой, обернутой вокруг него, чтобы помочь в его конфигурации (на самом деле это хеш-таблица хеш-таблиц, но это деталь реализации). Для получения дополнительной информации и ясности смотрите в проекте CommonServiceLocator на CodePlex , который определяет интерфейс, который поддерживают все основные контейнеры DI. С этой точки зрения объем памяти и время цикла должны быть небольшими, но вам нужно подумать о том, как вы собираетесь его использовать.

В проектах, над которыми я работал, я использовал DI-контейнер по двум основным причинам. Первый - это информация о конфигурации. Одним из примеров являются строки подключения; Я знаю, что вы могли бы поместить их в свой web.config, но это ограничивает ваше тестирование бизнес-логики, потому что A) вам нужно иметь весь веб-стек в игре и B) вам нужно изменить файл между юнит-тестами и интеграционными тестами , В проектах, над которыми я работал, я вставлял строку подключения из контейнера DI, настроенного в global.asa, который в основном делает его одиночным, как указано в других ответах. Это также работает для ссылочных типов (я знаю, что строка является ссылочным типом, но многие люди используют их / считают их типом предполагаемого значения), но вам нужно убедиться, что бизнес-логика не меняет своего состояния , Другими словами, он должен использовать метод получения только для свойств или вызывать только те методы, которые не имеют побочных эффектов для самой зависимости.

Что приводит ко второй причине, по которой я использовал DI, - для предоставления сервисных объектов. Как и в приведенной выше логике, SchedulingService - это логический дамп для домена, над которым я работаю. Он предоставляет сервис, который будет манипулировать или предоставлять данные, которые может использовать бизнес-логика, но сам по себе не изменяется. Любые изменения в себе обрабатываются либо во время построения, либо обрабатываются контейнером DI (который должен беспокоиться о счетчике ссылок и блокировке, что означает, что он также не должен этого делать). Это решит любые проблемы с многопоточностью, поскольку данные внутри контейнера неизменны с точки зрения бизнес-логики.

Из приложения ASP или любого приложения, к которому обращаются многие клиенты, использующие компоненты бизнес-логики, которые обращаются к другим зависимостям, DI может помочь с размером занимаемой памяти, но также может повредить его. Например, если у меня есть служба, которую нужно создавать при каждом запросе (но эта служба неизменна), то у меня будет объем памяти объекта X - количество одновременных сеансов. Но если у меня есть служба, которая вызывается очень редко, у меня будет память, выделяемая при запуске приложения, и она просто сидит и ждет, когда ее будут использовать. Я видел первое больше второго в коде, над которым я работал.

Надеюсь, это поможет.

1 голос
/ 31 октября 2009

Все это проблемы, но это верно, независимо от того, используете ли вы DI или нет.

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

1 голос
/ 31 октября 2009

Важным аспектом является определение правильного времени жизни объекта (синглтон против prototype - никогда не знаешь, каков правильный технический термин для этого), иначе вы можете столкнуться с некоторыми неприятными проблемами с многопоточностью. Что касается узких мест и проблем с памятью, они не имеют отношения к инфраструктурам DI, или, по крайней мере, у меня никогда не было ничего из этого, связанных с инфраструктурой DI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...