C#构建三层解决方案
我在C#中创建了一个win form解决方案。该解决方案有三个项目:前端层(FL)、业务层(BL)和数据层(DL) 前一层有各种形式。所有表单都实现了IForms接口 业务层拥有所有业务逻辑。所有业务逻辑类都实现IController接口 数据层具有与sql数据库通信的所有数据逻辑。所有数据逻辑类都继承IModel接口 我正在尝试使用MVC设计模式,但我有点挣扎。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
目标:当我按下表单中的按钮时,调用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);
}