C#构建三层解决方案

C#构建三层解决方案,c#,.net,wpf,winforms,model-view-controller,C#,.net,Wpf,Winforms,Model View Controller,我在C#中创建了一个win form解决方案。该解决方案有三个项目:前端层(FL)、业务层(BL)和数据层(DL) 前一层有各种形式。所有表单都实现了IForms接口 业务层拥有所有业务逻辑。所有业务逻辑类都实现IController接口 数据层具有与sql数据库通信的所有数据逻辑。所有数据逻辑类都继承IModel接口 我正在尝试使用MVC设计模式,但我有点挣扎。 目标:当我按下表单中的按钮时,调用BL类中的方法 如果我将BL dll添加到FL,那么我可以调用BL的方法 BL.Class cla

我在C#中创建了一个win form解决方案。该解决方案有三个项目:前端层(FL)、业务层(BL)和数据层(DL)

前一层有各种形式。所有表单都实现了IForms接口 业务层拥有所有业务逻辑。所有业务逻辑类都实现IController接口 数据层具有与sql数据库通信的所有数据逻辑。所有数据逻辑类都继承IModel接口

我正在尝试使用MVC设计模式,但我有点挣扎。
目标:当我按下表单中的按钮时,调用BL类中的方法

如果我将BL dll添加到FL,那么我可以调用BL的方法

BL.Class classObject = new BL.Class(this);
classObject.CallMethod();
在BL中,我想要调用该方法的对象的引用,所以我尝试添加FL dll的引用,但它表示循环dll引用

我想在BL类中有一个构造函数:

公共BL.Class(IView视图) { MessageBox(view.Name); }

我如何构建解决方案来实现这一点?请注意,解决方案很大,因此我无法将所有类合并到一个dll中

保重,,
FM

您正试图将表示逻辑注入业务层。您的BL不应创建消息框-这是表示层的责任。

您正试图将表示逻辑注入到业务层中。您的BL不应创建消息框-这是表示层的责任。

如果将两个层作为单独的项目实现(导致循环依赖),则无法让它们相互了解

一种方法是使用观察者模式。在业务类中设置事件,并让表示层订阅这些事件。当业务层完成其操作时,它可以触发事件并将结果传递回视图。业务类不需要了解表示层,它只知道有对象订阅了它,并避免创建循环依赖关系

更新:这里有一种让BL使用事件调用FL的方法。这是一种循环逻辑,但是如果你已经将代码围绕2层结构进行了解,那么你可以考虑这一点。
class BL
{
    public void CallFromFL (int parameter)
    {
        int result = DoSomeWork (parameter);
        if (OnComplete != null)
            OnComplete (result);
    }
    public event Action <int> OnComplete;
}

class FL
{
    void Foo ()
    {
        BL bl = new BL ();
        bl.OnComplete += this.getResult;
        bl.CallFromFL (5);
    }

    void GetResult (int result) {...}
}
BL类
{
public void CallFromFL(int参数)
{
int结果=DoSomeWork(参数);
如果(OnComplete!=null)
未完成(结果);
}
公共事件行动完成;
}
FL类
{
void Foo()
{
BL=新BL();
bl.OnComplete+=this.getResult;
bl.fl(5);
}
void GetResult(int result){…}
}

如果两个层作为单独的项目实现(导致循环依赖),则无法让它们相互了解

一种方法是使用观察者模式。在业务类中设置事件,并让表示层订阅这些事件。当业务层完成其操作时,它可以触发事件并将结果传递回视图。业务类不需要了解表示层,它只知道有对象订阅了它,并避免创建循环依赖关系

更新:这里有一种让BL使用事件调用FL的方法。这是一种循环逻辑,但是如果你已经将代码围绕2层结构进行了解,那么你可以考虑这一点。
class BL
{
    public void CallFromFL (int parameter)
    {
        int result = DoSomeWork (parameter);
        if (OnComplete != null)
            OnComplete (result);
    }
    public event Action <int> OnComplete;
}

class FL
{
    void Foo ()
    {
        BL bl = new BL ();
        bl.OnComplete += this.getResult;
        bl.CallFromFL (5);
    }

    void GetResult (int result) {...}
}
BL类
{
public void CallFromFL(int参数)
{
int结果=DoSomeWork(参数);
如果(OnComplete!=null)
未完成(结果);
}
公共事件行动完成;
}
FL类
{
void Foo()
{
BL=新BL();
bl.OnComplete+=this.getResult;
bl.fl(5);
}
void GetResult(int result){…}
}

我知道您的winforms编程,但您可能想看看WebFormsMVP或MVVM模式,了解一些想法

“在BL中,我想要调用该方法的对象的引用,因此我尝试添加FL dll的引用,但它显示为循环dll引用。”


特别是在WebFormsMVP项目中,参数是根据.Net framework中的方式在层之间传递的,例如(object sender,mySpecialEventArgs e)-参数“mySpecialEventArgs”中的第二个参数我知道你的winforms编程,但你可能想看看WebFormsMVP或MVVM模式,了解一些想法

“在BL中,我想要调用该方法的对象的引用,因此我尝试添加FL dll的引用,但它显示为循环dll引用。”


特别是在WebFormsMVP项目中,参数在层之间传递的方式取决于它们在.Net framework中的方式,例如(对象发送者,mySpecialEventArgs e)-参数“mySpecialEventArgs”中的第二个参数具有来回传递的所有信息。

您可以在BL中定义事件以便FL注册。当模型发生变化时,BL应该触发一个事件。由视图来处理它

您的BL在消息框中创建。如果您的视图是网络表单,该怎么办?BL不应该知道视图的细节

此外,BL项目不应该有对FL的dll引用。您需要在BL而不是FL中声明IView

编辑: 这是我以前用过的结构。BL定义了接口。如果视图想要使用BL,则必须实现接口。BL使用接口与视图交互。这样,您可以构建使用相同BL的不同视图

BL.dll

public interface IView
{
    /// <summary>Update the view</summary>
    void UpdateView(object myBusinessObject);

    /// <summary>Display message</summary>
    void ShowMessage(string msg);
}

public class BL
{
    // Model and View
    private IView _view;

    /// <summary>Constructor</summary>
    public BL (IView view)
    {
        _view = view;
    }

    public void foo()
    {
        // Do something

        // Show message
        _view.ShowMessage("Hello World");
    }
}
公共接口IView
{
///更新视图
void UpdateView(对象myBusinessObject);
///显示消息
void ShowMessage(字符串msg);
}
公共类BL
{
//模型和视图
私人IView_视图;
///建造师
公共BL(IView视图)
{
_视图=视图;
}
公共图书馆
private readonly Dictionary<Type,object> mServices = new Dictionary<Type,object>();
public void Add(Type type,object value)  { ...}
public object GetService(Type serviceType) { ... }
public void Remove(Type type)  { ... }
public T Resolve<T>()  { return (T)this.GetService(typeof(T)); } 
void ShowError(string message);
IMessageBoxService wMess = ServiceProvider.GetInstance().Resolve<IMessageBoxService>();
wMess.ShowError("My Error Message");
    interface IOrderController
{
    bool SaveOrder(order order);
    bool ValidateOrder(order order);
    order GetOrder();
}

public class OrderBaseController : IOrderController
{
    private OrderServiceFacade Orderhelper { get; set; }

    public OrderBaseController()
    {
        Orderhelper = new OrderServiceFacade();
    }

    public bool ValidateOrder(order objOrder)
    {
    }

    #region IOrderController Members

    public bool SaveOrder(order order)
    {
        bool success = false;
        if (ValidateOrder(order))
        {
           success = Orderhelper.SaveOrder(order);

        }

        return success;
    }

    #endregion

    #region IOrderController Members


    public order GetOrder()
    {
        throw new NotImplementedException();
    }

    #endregion
}
 public partial class Form1 : Form
{
    IOrderController Controller;

    public order OrderToBeSaved { get; set; }
    public Form1()
    {
        InitializeComponent();
        Controller = new OrderBaseController(); // you have the controller , 
        // controller creation can also be delegated to some other component but that's totally different issue.

        OrderToBeSaved = Controller.GetOrder(); // You got the order object here , once you get the order object you can bind its properties to the different control.



    }
}
 private void btnSave_Click(object sender, EventArgs e)
    {
        Controller.SaveOrder(OrderToBeSaved);
    }
 class OrderServiceFacade
{
    public bool SaveOrder(order order)
    {
       return  OrderDAO.SaveOrder(order);
    }
}
static class OrderDAO
{
    static public  bool SaveOrder(order order)
     {
            // put logic to access database and save the data.
     }

    static DataTable GetOrder(int OrderID);
}