2011-09-01 57 views
0

我正在尝试改进我的应用程序的设计,因此不是从表示层调用DataAccess层。我将尝试从BusinessObjects图层中的对象实现保存方法。但我不确定如何通过图层传递对象或属性。例如在我以前的设计中,我只是在表示层中创建了一个对象实例并为其分配属性,然后调用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(); 

那是possi竹叶提取?以及我的DAL如何?

编辑:解释我的要求

我会立足我的代码,现在在我的系统中一个非常重要的目标。

BusinessEntitiesLayer使用BusinessLogic层

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,但它给我的循环依赖错误!

它应该接收对象,并从我的项目强制转换为克鲁斯实体

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; 
} 

表示层使用BusinessEntities

输入控件(文本框, DropDownList等)

当点击保存按钮时,我将获取所有值,创建一个Cruise对象并调用Cruise。保存();

+1

扩展方法将帮助你 - http://msdn.microsoft.com/en-us/library/bb383977.aspx – rkg

回答

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 
    } 
} 

你会做这样的原因,是因为你的数据层可能没有你的业务对象的引用,因此,根本不知道它是什么。你将无法传递对象本身。这是通常的情况,因为通常它是引用数据层组件的业务对象程序集。

如果您拥有同一装配中的所有内容,则上述内容不适用。但是,如果您决定将数据层重构为其自己的模块(这通常是它的结果,而且是很好的设计),那么传递该对象将会中断,因为那样会失去对您业务对象的引用。如果你添加一个新的字段或成员,你应该知道你将不得不更新你的对象和你的数据图层。这只是添加新内容时给出的。

我可以写一些关于这方面的优秀设计实践的博客,但这是我的建议。

+0

我明白你要去哪里,但是我不喜欢在方法签名中列出所有成员的想法,我们应该传递类并封装属性,如果你有25个成员呢!此外,你的DAL不是通用的,如果两个对象有一个int和一个字符串呢? –

+0

该文章将是伟大的! :)认真。我需要学习好的设计,但它都是复杂而庞大的书籍! ..以及关于我的图层我在解决方案中有一个单独的程序集中有4个图层。我不确定我是否理解你传递对象的东西。但我需要我的DAL使用BusinessEntites程序集,并且不会将属性作为参数发送,因为它们很多!如果我对我的对象进行了任何更改,我将需要进行很多编辑。也许这就是你想说的话,有时我会在答案中迷失,对此感到遗憾 – lKashef

+0

@Davide Piras,如果一个对象有25个成员,那么你可能不会这样设计它。设计通常是根据需求来完成的,他的文章中的要求也是非常基本和模糊的。您可以选择许多设计模式进行架构和实施,但都是要回到需求。 at IKashef我会在今天晚些时候写一篇文章。我的网址位于我的档案 –

1

如果按照这个模式,你将有对象定义本身内部的节能逻辑,所以当你从PL拨打:

public void SaveObject() 
{ 
    DAL.SaveObject(this); 
} 

obj.SaveObject(); 

这将在对象本身发生并且您的DAL与上面显示的保持一致。

这是一个设计问题,我不会把保存在对象内部的逻辑,但我会有一个BusinessManager或ObjectMapper从DAL读取并保存到DAL。

一般来说,读取,加载和保存在同一个地方BusinessObject或BusinessManager中是一种很好的做法,但它们可以轻松地找到并更新,只需添加或更改字段即可。

+0

嗯,实际上,我有BusinessLogic层.. Object.Save()调用ObjectBLL.Save()并验证数据然后将其发送到DAL.Save(object obj)。这当然是我想要实现的,但它给了我一个循环依赖关系错误,当然,在DataAccess层使用我的实体层是必不可少的。无论如何,我对设计不太好,所以可以发布一些样本来说明如何以及在哪里实施Save方法以及您选择哪些图层? – lKashef

+0

n层方法的主要规则之一是不要引用一切。 PL仅引用BL和BL(业务逻辑)引用DAL,DAL对PL来说不可用,没有循环引用。然后在一个名为Core或Common的分离类库中定义实体,并由所有图层引用。我们还为实体和接口使用分离的类库,PL仅引用接口BL两者,创建实体并将接口返回给PL。相当稳固! –

+0

我明白了,但我现在有4层,每个都在一个单独的项目中。 PL,BO,BL,DAL ..我知道如何引用3层,但现在怎么样?你认为在Object层实现一个保存方法是件好事。我只是认为将save方法设置为非静态而不是直接调用BLL或DAL方法会很好 – lKashef

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(); 
     } 
} 

所以在这种方式,您仍然可以添加工作人员赴域对象,而不在域对象的逻辑连接。

+0

对不起,我花了那么长时间。但是如果你不介意的话,你会简化你的例子吗? – lKashef

相关问题