Ваш вопрос нечетный. Вы сомневаетесь, что вы пишете свой бизнес-уровень для приложения Winforms по-другому, чем в веб-приложении, но если вы правильно применяете слоирование, бизнес-уровень должен быть полностью независим от используемой технологии. Поэтому в этом случае, если вы примените шаблон зависимостей зависимостей на бизнес-уровне веб-приложения, вы также должны применить его на бизнес-уровне настольного приложения.
В настоящее время я работаю над проектом Winforms и широко использую шаблон Injection Dependency (и контейнер IoC). Для меня нет вопроса, следует ли использовать DI; естественно следует применять принципы SOLID. Независимо от того, следует ли использовать контейнер IoC, это совершенно другой вопрос, хотя для типов приложений я пишу и использую типы архитектуры, я не могу представить себе жизнь без нее.
Несмотря на то, что настольные приложения отличаются по своему характеру, чем веб-приложения, я использую те же шаблоны для обоих типов приложений. Например, я использую инъекции конструктора в классах моего Windows Forms и те формы, в основном, зависят от нескольких общих интерфейсов, а именно:
IRepository<TEntity>
(шаблон репозитория) для загрузки объектов.
IQueryHandler<TQuery, TResult>
для выполнения сложных или пользовательских запросов разного рода.
ICommandHandler<TCommand>
для выполнения прецедентов (обработка действий пользователя).
Я использую те же абстракции в создаваемых веб-приложениях.
Эти интерфейсы помогли мне несколько месяцев назад, чтобы изменить это настольное приложение из двухуровневого приложения (все бизнес-логики, запущенные в настольном приложении), в трехуровневое приложение (где вся бизнес-логика теперь перемещается в WCF оказание услуг). Мы смогли сделать это без необходимости менять код в Формах.
В двухуровневой модели мы не вводили сразу ICommandHandler<TCommand>
реализаций, а вводили (прокси-класс) одного прокси-класса, который создавал бы новую реализацию каждый раз, когда он был вызван. Например, когда форма, называемая впрыском ICommandHandler<ProcessOrder>
, фактический CommandHandlerProxy<ProcessOrder>
начнет всю жизнь (образ жизни, который имитирует образ жизни для каждого запроса в веб-приложении) и создаст реальный класс ProcessOrderCommandHandler
, который будет выполнять фактическую логику.Сделав это, мы обеспечили, чтобы одна единица работы (Entity Framework DbContext
в нашем случае) была бы введена во все классы в рамках этого «запроса». Все, конечно, с введением зависимостей вплоть до графика вызовов.
В новой модели 3-уровневой, формы вводятся с WcfProxyCommandHandler<TCommand>
, который будет сериализовать данную команду для JSON и отправить его на службу WCF, который заберет его, десериализует команду, создает ProcessOrderCommandHandler
и выполняет команду.
Но имейте в виду, что эта модель, вероятно, очень отличается от того, что вы, вероятно, использовали. Например:
- Настоящие объекты скрыты за службой WCF. Настольное приложение ничего не знает о них.
- Вместо этого DTO s возвращаются из службы WCF, когда запрашиваются данные через абстракцию
IQueryHandler<TQuery, TResult>
.
- Мы используем Entity Framework 5 (классы POCO с T4 и дизайнером).
- Эти DTO (в основном) используются для чтения; они не отправляются обратно на сервер для обновления.
- Любой запрос об изменении состояния (исполнение прецедента) выполняется путем отправки командного сообщения на сервер (через абстракцию
ICommandHandler<TCommand>
).
- Один единственный вариант использования инкапсулирован в один класс, который реализует интерфейс
ICommandHandler<TCommand>
.
И, как я уже сказал, это инъекция зависимостей полностью вниз, и этот и описанный дизайн дают нам большую гибкость. Например:
- Нам очень легко добавить новые функции.
- Нам очень легко добавить новые сквозные проблемы.
- Он опускает ментальный барьер; это упрощает работу приложения и значительно реже ломается неожиданными способами.
Существует, однако, одна вещь, которую я узнал в процессе:
- Связывание в WinForms оптимизирован для работы с наборами данных. Если вы попробуете что-нибудь еще (объекты Poco, Entity Framework и т. Д.), Вы получите некоторые очень неприятные моменты, когда вы узнаете, что поддержка чего-либо еще, кроме DataSets, минимальна. Понятно, что Microsoft не инвестировала в эту область и больше не будет инвестировать в эту область. Чтобы обойти эти ограничения, мы написали собственную реализацию
BindingList<T>
и очень сложно создать реализацию, которая корректно работает с сортировкой и фильтрацией (тем более, что наши DTO не реализуют INotifyPropertyChanged
). Мы также wrote our own infrastructure добавили поддержку валидации DataAnnotations для Winforms.
Если вы хотите узнать больше о проектах, которые я использую, пожалуйста, прочитайте эти статьи:
- Meanwhile... on the command side of my architecture
- Meanwhile... on the query side of my architecture
- Writing Highly Maintainable WCF Services
FWIW, пока я не охватывают разработку Windows Forms с помощью DI, I * do * охватывают разработку WPF с помощью DI в [моей книге] (http://bit.ly/b5Vir7). Архитектурно, эти две платформы очень похожи, поэтому, возможно, вы найдете это полезным ... –
@luis_laurent Вы обязательно найдете книгу полезной (пока вы ее ждёте, обязательно прочитайте топ- проголосовали за меня - для меня они были наиболее образовательными материалами, охватывающими эту тему) –
, связанный: http://stackoverflow.com/questions/4129092/how-to-use-ninject-in-a-windows-forms -приложение –