我正在尝试改进我的应用程序的设计,因此不是从表示层调用DataAccess层。我将尝试从BusinessObjects图层中的对象实现save方法。但我不确定如何通过图层传递对象或它的属性。例如,在我的旧设计中,我只是在表示层中创建我的对象的实例并分配它的属性,然后调用DataAccess方法将此信息保存在数据库中,并将对象作为参数传递,如图所示。
DAL
public static void SaveObject(Object obj)
{
int id = obj.id;
string label = obj.label;
}
PL
Object obj = new Object();
obj.id = 1;
obj.label = "test";
DAL.SaveObject(obj);
但我只想在 PL
中执行此操作Object obj = new Object();
obj.id = 1;
obj.label = "test";
obj.SaveObject();
这可能吗?我的DAL怎么样?
修改 解释我的要求
我现在将我的代码基于我系统中一个非常重要的对象。
BusinessEntitiesLayer 使用BusinessLogic Layer
namespace BO.Cruises
{
public class Cruise
{
public int ID
{ get; set; }
public string Name
{ get; set; }
public int BrandID
{ get; set; }
public int ClassID
{ get; set; }
public int CountryID
{ get; set; }
public string ProfilePic
{ get; set; }
public bool Hide
{ get; set; }
public string Description
{ get; set; }
public int OfficialRate
{ get; set; }
public string DeckPlanPic
{ get; set; }
public string CabinsLayoutPic
{ get; set; }
public List<Itinerary> Itineraries
{ get; set; }
public List<StatisticFact> Statistics
{ get; set; }
public List<CabinRoomType> RoomTypesQuantities
{ get; set; }
public List<CabinFeature> CabinFeatures
{ get; set; }
public List<CruiseAmenity> Amenities
{ get; set; }
public List<CruiseService> Services
{ get; set; }
public List<CruiseEntertainment> Entertainment
{ get; set; }
public List<CustomerReview> CustomerReviews
{ get; set; }
}
}
BusinessLogicLayer 使用DataAccessLayer
实际上这个层是为了验证我的对象然后调用DAL方法,但我现在没有实现任何验证,所以我只是用它来调用DAL方法。
public static void Save(object cruise)
{
CruisesDAL.Save(cruise);
}
DataAccessLayer 尝试引用BussinessEntities,但它给了我循环依赖项错误!
它应该接收对象并将其转换为Cruise实体
public static void Save(object cruise)
{
Cruise c = cruise as Cruise;
//access the object c properties and save them to the database
}
我项目的代码示例:
public static List<Cruise> GetCruisesList()
{
string commandText = "SELECT ID, Name + CASE Hide WHEN 1 Then ' (Hidden)' ELSE '' END AS Name FROM Cruises";
List<Cruise> cruises = new List<Cruise>();
Cruise cruise;
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
using (SqlCommand command = new SqlCommand(commandText, connection))
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
cruise = new Cruise();
cruise.ID = Convert.ToInt32(reader["ID"]);
cruise.Name = reader["Name"].ToString();
cruises.Add(cruise);
}
}
}
}
return cruises;
}
PresentationLayer 使用BusinessEntities
输入控件(TextBoxes,DropDownList等)
单击保存按钮时,我获取所有值,创建一个Cruise对象并调用Cruise.Save();
答案 0 :(得分:2)
您应该避免将域模型与持久性逻辑混合使用。 上面给出的例子将成为紧密耦合解决方案。 为了实现.SaveObject(),您可以在BL中创建可以完成工作的扩展方法。
BL *
public static class ObjectPersistanceExtensions{
public static SaveObejct<T>(this IBaseEntity obj){
IObjectDal<T> _dal = AvailableSerices.Obtain<IObjectDal<T>>();
_dal.AddObject(obj);
_dal.Commit();
}
}
因此,通过这种方式,您仍然可以向域对象添加工作组,而无需在域对象中耦合逻辑。
答案 1 :(得分:1)
如果您遵循这种模式,您将在对象定义中拥有保存逻辑,因此当您从PL调用时:
obj.SaveObject();
这将发生在对象本身:
public void SaveObject()
{
DAL.SaveObject(this);
}
并且您的DAL保持与上面显示的相同。
这是一个设计问题,我不会把保存的逻辑放在对象中但我会有一个BusinessManager或一个ObjectMapper来读取DAL并保存到DAL。
一般来说,这是一个很好的做法,可以在同一个地方,BusinessObject或BusinessManager中进行读取或加载和保存,但是如果您添加或更改字段,则可以轻松找到它们并轻松更新。
答案 2 :(得分:1)
将对象本身传递给数据层通常有点时髦。相反,我建议您让对象与数据层进行通信,并让数据层执行其操作。
internal static class DataLayer {
public static bool Update(int id, string label) {
// Update your data tier
return success; // bool whether it succeeded or not
}
}
internal class BusinessObject {
public int ID {
get;
private set;
}
public string Label {
get;
set;
}
public bool Save() {
return DataLayer.Update(this.ID, this.Label); // return data layer success
}
}
你这样做的原因是因为你的数据层可能没有对你的业务对象的引用,因此不知道它是什么。您将无法传递对象本身。这是一个常见的场景,因为通常是您的业务对象程序集引用您的数据层程序集。
如果您拥有相同组件中的所有内容,则上述内容不适用。但是,如果您决定将数据层重构为自己的模块(通常是它的结果,并且设计良好),则传递对象将会中断,因为它会丢失对业务对象的引用。
无论哪种方式,您都应该知道,如果添加新字段或成员,则必须更新对象和数据层。当你添加新东西时,这只是给定的。
我可能会为此写一些关于一些好的设计实践的博客,但这是我的建议。