Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在MVC模式中实现类之间的通信? 前言:这个问题不是关于ASP.NET MVC框架的。_C#_Events_Design Patterns_Model View Controller - Fatal编程技术网

C# 如何在MVC模式中实现类之间的通信? 前言:这个问题不是关于ASP.NET MVC框架的。

C# 如何在MVC模式中实现类之间的通信? 前言:这个问题不是关于ASP.NET MVC框架的。,c#,events,design-patterns,model-view-controller,C#,Events,Design Patterns,Model View Controller,编辑:更清楚地说,该应用程序是用C#编写的游戏,因此各种web框架都不适用 在使用MVC模式构建某些东西时,如何最好地将类与事件连接起来 我想写一些MVC代码,这样我就可以更多地了解设计模式。我理解为什么模式的这三个元素中的每一个都应该是独立的,但我不确定如何实现将它们连接在一起。我是用C#写这篇文章的,我对C#也是新手,我觉得应该使用事件。我主要不确定我应该如何正确订阅/取消订阅这些活动,我需要一个理智的检查 例如,我将发布视图/控制器类。在本例中,视图希望发送DataRequest事件,控

编辑:更清楚地说,该应用程序是用C#编写的游戏,因此各种web框架都不适用


在使用MVC模式构建某些东西时,如何最好地将类与事件连接起来

我想写一些MVC代码,这样我就可以更多地了解设计模式。我理解为什么模式的这三个元素中的每一个都应该是独立的,但我不确定如何实现将它们连接在一起。我是用C#写这篇文章的,我对C#也是新手,我觉得应该使用事件。我主要不确定我应该如何正确订阅/取消订阅这些活动,我需要一个理智的检查

例如,我将发布视图/控制器类。在本例中,视图希望发送DataRequest事件,控制器希望订阅该事件,以便将其传递给模型。另一方面,控制器将在某个时刻引发视图应该订阅的DataUpdate事件。我实现他们相互订阅的方式有意义吗

////////////////////////////////////////////////////
public class UIScreenView
{
    public event System.EventHandler<System.EventArgs> DataRequestedEvent;

    //====================================
    private void DataUpdatedEventHandler(object sender, System.EventArgs args);


    //====================================
    //====================================
    public void Subscribe(UIScreenController controller)
    {
        controller.DataUpdatedEvent += DataUpdatedEventHandler;
        controller.Subscribe(this);
    }

    //====================================
    //====================================
    public void UnSubscribe(UIScreenController controller)
    {
        controller.DataUpdatedEvent -= DataUpdatedEventHandler;
        controller.UnSubscribe(this);
    }
}
////////////////////////////////////////////////////
公共类用户界面视图
{
public event System.EventHandler DataRequestedEvent;
//====================================
私有void DataUpdatedEventHandler(对象发送方,System.EventArgs args);
//====================================
//====================================
公共无效订阅(UIScreenController控制器)
{
controller.DataUpdateEvent+=DataUpdateEventHandler;
控制器。订阅(此);
}
//====================================
//====================================
公共无效取消订阅(UIScreenController控制器)
{
controller.DataUpdateEvent-=DataUpdateEventHandler;
控制器。取消订阅(此);
}
}
以及控制器:

public class UIScreenController
{
    private UIScreenView view;

    public event System.EventHandler<System.EventArgs> DataUpdatedEvent;

    private void DataRequestedEventHandler(object sender, System.EventArgs args);

    public void Init(UIScreenView v)
    {
        view = v;

        if (view != null)
        {
            view.Subscribe(this);
        }
    }

    ~UIScreenController()
    {
        if (view)
        {
            view.UnSubscribe(this);
            view = null;    
        }
    }

    public void Subscribe(UIScreenView view)
    {
        view.DataRequestedEvent += DataRequestedEventHandler;
    }

    public void UnSubscribe(UIScreenView view)
    {
        view.DataRequestedEvent -= DataRequestedEventHandler;
    }

    private void DataRequestedEventHandler(object sender, System.EventArgs args)
    {
        //request data from model
    }
}
公共类UIScreenController
{
私隐视野;
public event System.EventHandler DataUpdateEvent;
私有void DataRequestedEventHandler(对象发送方,System.EventArgs args);
公共无效初始(UIScreenView v)
{
视图=v;
如果(视图!=null)
{
查看。订阅(本);
}
}
~UIScreenController()
{
如果(视图)
{
查看。取消订阅(此);
视图=空;
}
}
公共无效订阅(UIScreenView视图)
{
view.DataRequestedEvent+=DataRequestedEventHandler;
}
公共无效取消订阅(UIScreenView视图)
{
view.DataRequestedEvent-=DataRequestedEventHandler;
}
私有void DataRequestedEventHandler(对象发送方,System.EventArgs args)
{
//从模型请求数据
}
}

你有点倒退了。MVC(与WebForms之类的东西相比)的一个主要教训是web应用程序中没有任何“事件”。您所拥有的只是HTTP规范,它将客户端和服务器之间的事务定义为GET/POST(不太常见的是PUT/DELETE)。MVC中没有“点击按钮”这样的东西。相反,您有一个来自页面上表单的HTTP POST

此外,每个HTTP请求都与之前的请求完全断开连接,因此没有一个好方法可以保持客户端和服务器之间的连接打开。服务器真正能做的就是接受请求,然后提供适当的响应。所有试图混淆这种脱节现实的尝试都导致了较弱的web框架,而不是更好的框架

各种MVC框架主要执行所谓的“模型绑定”。HTTP POST或GET不附带从类构造的“对象”;它真正拥有的只是POST或GET变量和头等等。MVC世界的模型绑定器基本上采用这些简单的参数,并根据预期的类类型(通常在控制器中定义,或按照约定)动态地从中构造对象。然后,控制器允许您基于这些对象执行代码操作,并最终以视图的形式向下发送响应

此时,与其用自己的框架重新发明轮子,不如选择1-2个流行的MVC框架并学习它们的范例。我碰巧在ASP.NETMVC中工作并且喜欢它,但是RubyonRails非常擅长。对于每种主要语言,可能都有1-2个成熟、可靠的MVC框架,因此您应该从使用您熟悉的语言的框架开始


在您熟悉了现有的MVC框架之后,您可以开始考虑如何以不同的方式实现它,如果这是您最终的目标的话

首先,您描述的是模型视图演示器。到目前为止,我找到的最好的描述是Robert Martin的“c#中的敏捷原则、模式和实践”

其次,MVP不需要活动。其思想是presenter和view相互引用,并且知道它们的接口,以便直接调用数据请求/更新


第三,对于没有经验的开发人员来说,该模式可能会很麻烦。这样做的好处是,视图可以替换为假视图,因此您可以轻松地对演示者进行单元测试。然而,如果从oop开始,将视图和演示者合并到一个类中的方法可能会更简单。

您所做并尝试的是MVP模式,而不是MVC。简而言之,MVC模式用于请求-响应体系结构,而不是事件驱动的。流程是:

  • 用户界面执行请求
  • 控制器接受请求
  • 控制器处理请求(如访问模型等)
  • 控制器将响应发送到用户界面
如果你想
public class SaveDataController
{
    public SaveData[] GetSaveData()
    {
        return Model.GetSaveData();
    }
}
public void LoadGameButton_Click(object sender, EventArgs e)
{
    SaveDataController controller = new SaveDataController();
    SaveData[] saveData = controller.GetSaveData();
    SaveDataList.DataSource = saveData;
}