简体   繁体   English

如何在C#项目中设计View逻辑

[英]How do I design View logic into c# projects

I have three c# projects in my solution. 我的解决方案中有三个c#项目。 One is a console app that simply calls into a class library project. 一个是控制台应用程序,它仅调用一个类库项目。 The class library project does all the processing for the application. 类库项目对应用程序进行所有处理。 Then there is a WinForm project that displays a form and then when a button is pressed, calls the same logic in the class library project. 然后是一个WinForm项目,该项目显示一个表单,然后当按下按钮时,在类库项目中调用相同的逻辑。 As a result, there are two ways to run the logic, via the Console or via a Windows UI (WinForm). 因此,有两种方法可以通过控制台或Windows UI(WinForm)运行逻辑。

My problem is that part way through the class library logic, if the UI app is being used, I want a custom WinForm form to appear to ask the user a question. 我的问题是,在使用类库逻辑的过程中,如果正在使用UI应用程序,则我希望自定义WinForm表单出现来向用户提问。

In the Console app, I want the same place in the logic to simply write out to the Console. 在控制台应用程序中,我希望逻辑中的相同位置可以简单地写到控制台。 In my understanding of architecture, you don't want the class library project to contain WinForm logic and require it to have references to all the WinForm references. 在我对体系结构的理解中,您不希望类库项目包含WinForm逻辑,而要求它具有对所有WinForm引用的引用。 But how do I make a call to the WinForms project (or something else) to display the custom WinForm form? 但是,如何调用WinForms项目(或其他方法)以显示自定义WinForm表单? There would be a circular reference where the class library would reference the main WinForm app and the WinForm app would reference the class library project. 将有一个循环引用,其中类库将引用主WinForm应用程序,而WinForm应用程序将引用类库项目。

What is the standard way of doing this? 这样做的标准方法是什么?

Why not define an inteface, IOutputHandler, that has a method called DisplayOutput. 为什么不定义一个接口IOutputHandler,它具有一个称为DisplayOutput的方法。 You would have 2 implementations of it, one for your winforms app and one for the console. 您将有2种实现,一种用于winforms应用,另一种用于控制台。 You'd call the correct version of it at runtime. 您将在运行时调用正确的版本。 You could modify your class library to have a private field instance for the IOutputHandler, and then plug in the proper one at runtime. 您可以修改您的类库,使其具有IOutputHandler的私有字段实例,然后在运行时插入适当的实例。

You could raise an event in the class library that is listened to/registered from whatever your UI/Console layer is. 您可以在类库中引发一个事件,该事件可以从您的UI / Console层监听或注册。 That way it can decide to act on the event if it is deemed necessary in as many places as you desire. 这样,如果您认为有必要,可以决定在事件中采取行动。 It really depends on how your architecture is setup. 这实际上取决于您的体系结构是如何设置的。

You could create an interface that your library defines to communicate back to the caller, then have both your calling apps define their own implementaions of this interface, the library calls the methods on this interface and knows nothing of the implmentation. 您可以创建一个接口,库将定义该接口以与调用方进行通信,然后让两个调用应用程序定义该接口自己的实现,该库将调用此接口上的方法,而对实现一无所知。

The caller processes the methods accordingly... 调用者将相应地处理方法...

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!");
    }
}

This is where you need clear definition between your logic layer and your UI layer. 这是您需要在逻辑层和UI层之间进行清晰定义的地方。 It's perfectly acceptable and normal to put this sort of logic in your UI, since that bit can't reasonably live within the logic layer, as it is UI dependent. 在用户界面中放置这种逻辑是完全可以接受和正常的,因为该位不能合理地存在于逻辑层中,因为它取决于用户界面。

Your logic should never, ever refer to any kind of UI component. 您的逻辑永远不要引用任何类型的UI组件。 If it does, it's wrong, and you need to redesign it to remove UI dependencies completely. 如果是这样,那是错误的,您需要重新设计它以完全删除UI依赖项。

虽然接口答案可能是更好的解决方案,但如果仅是一种方法,则可以只使用委托将Console或WinForm方法传递给类库。

Another solution 另一种解决方案

In your class lib.. 在你的类库中

public void MyLibMethod(Action<string> callBack)
{
      callBack("Yeh baby...");
}

Then call 然后打电话

Class.MyLibMethod(s=> Console.WriteLine(s));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM