Я бы сделал это:
.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 и получение любого инвертирования управляющего компонента этим более конкретным интерфейсом так же, как я объяснил выше .
Я полагаю, что дал достаточно советов, чтобы понять, как структура моего решения и организация сборки, а также инверсия управления могут дать вам такую технологическую независимость, что вы смотрите между слоями вашего проекта и внутри них!;)