Как настроить решение, в котором есть проекты для winforms и web? - PullRequest
0 голосов
/ 12 мая 2011

В моем решении у меня есть несколько проектов:

  • Основной проект.Этот проект содержит все мои классы и интерфейсы
  • Проект Winforms
  • Веб-проект

Ключевой особенностью приложения является динамическое создание элементов управления.У меня есть класс с перечислением, и на основе значения перечисления должен быть возвращен определенный элемент управления.Итак, я создал фабрику в основном проекте так:

public IControl Create(Enum enum)
{
    switch(enum)
    {
      case "enum.A":
        return new CheckBoxControl();
      case "enum.B":
        return new RadioControl();
    }
}

Задница, как вы уже догадались, у меня есть пользовательские элементы управления.Все они наследуются от интерфейса (IControl).Но в этом случае CheckBoxControl и RadioControl являются элементами управления WinFroms.

Теперь эти элементы управления находятся в основном проекте.Я не хочу этого, потому что это базовая библиотека, и я хочу, чтобы эта библиотека была независимой от платформы.

Мне нужны элементы управления winforms в проекте WinCore и элементы WebControls в проекте WebCore.Проблема в том, как я могу вернуть правильные элементы управления из основного проекта?

Оба проекта WebCore и WinCore нуждаются в ссылке на основной проект, потому что основной проект содержит мои объекты.Это означает, что я не могу установить ссылку из основного проекта web- или wincore.

Как решить эту проблему?

Ответы [ 3 ]

1 голос
/ 12 мая 2011

Я бы сделал это:

  • .Core должен быть сборкой, содержащей бизнес .

  • .Shared должна быть сборкой, содержащей инфраструктуру, базовые классы и интерфейсы, которые не зависят от платформы и технологии - так что это позволит вам повторно использовать ее в любом проекте, избегая нежелательных зависимостей -.

  • .Web - это сборка, содержащая веб-функциональность

  • .Web.Forms должна быть сборкой, содержащей только веб-формы и веб-элементы управления .

  • .Windows должнабыть сборкой, связанной с Windows-ориентированной функциональностью.

  • .Windows.Forms должна быть сборкой, содержащей только Windows Forms и Controls.

При такой структуре сборки интерфейс IControl должен находиться в .Shared сборке иНа s следует ссылаться .Core , позволяя коду добавлять экземпляры IControl без необходимости в зависимостях от технологии.

Кроме того, этого решения достаточно, чтобы разрешить .Windows , .Windows.Forms , .Web и .Web.Forms ссылка .Core и / или .Shared .


ОБНОВЛЕНИЕ:

Это всего лишь предложение, но почему вы используете перечисление на своей фабрике?Вы можете сделать это:

public TControl Create<TControl>() where TControl : IControl, new()
{
    IControl control = new TControl();

    // Control initialization work

    return control;
}

Что вы думаете?

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


ОБНОВЛЕНИЕ 2:

Как инверсия управления может помочь вам в вашей проблеме?

Фактически, если вы зарегистрируете инверсию компонентов управления, вы получите доступ к ним по типу или по уникальному идентификатору.

Допустим, у вас есть интерфейс IControl (службы) и WindowsTextBox и WebFormsTextBox, оба реализующие IControl.В вашем файле конфигурации вы собираетесь иметь два компонента, которые имеют одинаковый тип сервиса (интерфейс) и две разные реализации, и они будут помечены двумя разными идентификаторами:

  • WindowsTextBox is IControl,с идентификатором WindowsTextBox .
  • WebFormsTextBox - это IControl, с идентификатором WebFormsTextBox .

Теперь у вас есть оба элемента управления, зарегистрированные в инверсииКонтейнер управления, и вы можете использовать фабрику извлечения компонентов собственного API следующим образом:

  • IoCFactory.GetComponents<IControl>().Вам нужны все реализации IControl в инверсии тока контейнера управления - в вашем случае это не рекомендуется!-.

  • IoCFactory.GetComponent<IControl>("WindowsTextBox").Вы хотите, чтобы реализация IControl называлась "WindowsTextBox".

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

Где точка инверсии управления в вашей проблеме?Обратите внимание, что вы используете класс factory , который будет помещен в общую библиотеку, чтобы вы могли использовать его где угодно, и то же самое для интерфейса IControl .

Хорошо, ядумаю, вам нужны конкретные контрольные экземпляры.Вы можете сделать две вещи:

  • Просто поиграть с IControl экземплярами и везде, где в технологической логике приведите его к его конкретному типу - например, WindowsTextBox - и продолжайте.

  • Создайте столько интерфейсов, сколько конкретнее IControl , чтобы некоторая логика могла получить доступ к некоторым свойствам и методам, которые ближе к конкретному набору функций управления. Примером этого может быть интерфейс ITextBox и получение любого инвертирования управляющего компонента этим более конкретным интерфейсом так же, как я объяснил выше .

Я полагаю, что дал достаточно советов, чтобы понять, как структура моего решения и организация сборки, а также инверсия управления могут дать вам такую ​​технологическую независимость, что вы смотрите между слоями вашего проекта и внутри них!;)

0 голосов
/ 12 мая 2011

Вы должны использовать другую фабрику в проекте WinForms и в веб-проекте. Создайте интерфейс IControlFactory, который реализован на обеих фабриках, и создайте экземпляр фабрики соответствующего типа в каждом проекте.

0 голосов
/ 12 мая 2011

Добавьте Controlmanager в ядро ​​с помощью метода RegisterControls. Webcore вызывает метод Controlmanager.RegisterControls. Основное приложение общается только с ядром

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