У меня есть три c# проекта в моем решении. Каждый - консольное приложение, которое просто звонит в проект библиотеки классов. Проект библиотеки классов делает всю обработку для приложения. Затем существует проект WinForm, который отображает форму и затем когда кнопка нажимается, называет ту же логику в проекте библиотеки классов. В результате существует два способа выполнить логику через Консоль или с помощью Windows UI (WinForm).
Моя проблема состоит в том, что часть путь через логику библиотеки классов, если приложение UI используется, я хочу, чтобы пользовательская форма WinForm, казалась, задавать пользователю вопрос.
В Консольном приложении я хочу, чтобы то же место в логике просто выписало к Консоли. В моем понимании архитектуры Вы не хотите проект библиотеки классов содержать логику WinForm и потребовать, чтобы это имело ссылки на все ссылки WinForm. Но как я звоню проекту WinForms (или что-то еще) для отображения пользовательской формы WinForm? Была бы циклическая ссылка, где библиотека классов сошлется на основное приложение WinForm, и приложение WinForm сослалось бы на проект библиотеки классов.
Каков стандартный способ сделать это?
Вы можете создать интерфейс, который ваша библиотека определит для обратной связи с вызывающим аппликантом, затем оба ваших вызывающих аппликанта определят свои собственные реализации этого интерфейса, библиотека вызовет методы на этом интерфейсе и ничего не будет знать о его имплантации.
Звонящий соответственно обрабатывает методы...
public interface IProgressReporter
{
void ReportMessage(string message);
}
public class WinFormsProgressReporter : IProgressReporter
{
public void ReportMessage(string message)
{
MessageBox.SHow(message);
}
}
public class ConsoleAppProgressReporter : IProgressReporter
{
public void ReportMessage(string message)
{
Console.WriteLine(message);
}
}
public class LibraryClass
{
public static void SomeMethod(IProgressReporter rep)
{
rep.ReportMessage("Wooooohooooo!");
}
}
С учетом документации по PowerShell, вариант -NonInteractive может помочь здесь
-121--4950937-Здесь необходимо четкое определение между логическим уровнем и уровнем пользовательского интерфейса. Вполне приемлемо и нормально помещать логику такого рода в ваш пользовательский интерфейс, так как этот бит не может разумно жить в пределах логического уровня, так как он зависит от пользовательского интерфейса.
-121--4950905-Почему бы не определить интерфейс IOutateHandler, который имеет метод DisplayOutput. У вас будет 2 его реализации, одна для вашего приложения winforms и одна для консоли. Вы бы назвали правильную версию во время выполнения. Можно изменить библиотеку классов, чтобы иметь частный экземпляр поля для IOutableHandler, а затем подключить соответствующий экземпляр во время выполнения.
Для того, чтобы пройти 2 параметра к действию, просто определите действие вставки в виде AN Action
и когда вы называете это так, как это:
var custom = new CustomClass((o,u) => {LayoutRoot.Children.Add(o); somethingElse(u)});
-121--3274128- Ваша логика должна никогда не относится к любому виду компонента пользовательского интерфейса. Если это так, это неправильно, и вам нужно отрезотировать его, чтобы полностью удалить зависимости пользовательских интерфейсов.
Это то, где вам нужно четкое определение между логическим слоем и вашим слоем UI. Это совершенно приемлемо и нормально, чтобы поставить эту логику в вашем интерфейсе UI, поскольку этот бит не может разумно жить в логическом слое, так как он зависит от интерфейса.
Для того, чтобы пройти 2 параметра к действию, просто определите действие вставки в виде действия Action
и когда вы называете это так, как это так:
var custom = new CustomClass((o,u) => {LayoutRoot.Children.Add(o); somethingElse(u)});
-121--3274128- В то время как ответы интерфейса, вероятно, являются лучшими решениями, если это просто один метод, который вы можете просто использовать делегат для передачи консоли или метода WinForm в библиотеку классов.
Другое решение
В вашем классе lib ..
public void MyLibMethod(Action<string> callBack)
{
callBack("Yeh baby...");
}
Тогда звоните
Class.MyLibMethod(s=> Console.WriteLine(s));
Вы можете поднять событие в библиотеке классов, которое прослушивается/зарегистрировано с любого уровня UI/Console. Таким образом, он может принять решение действовать по событию, если это будет сочтено необходимым в таком количестве мест, в каком вы пожелаете. Это действительно зависит от того, как настроена ваша архитектура.