我有一个架构问题。我有DOL项目与poco类(数据库中的等价表),BLL项目和UI项目。 UI项目引用了BLL项目,BLL项目引用了DAL项目。
我想在UI项目数据中显示例如来自数据库的表Product。 我应该在BLL项目类中创建与DAL项目中的poco类相同的内容并将其返回到UI项目并显示它吗?
所以这是我在DAL中的poco类(数据库中的等效表):
public class Product
{
public int ID {get; set; }
public string Name {get; set; }
public String Address {get; set; }
}
在BLL中,我创建了与上面的poco类相同的业务对象:
public class ProductBO
{
public int ID { get; set; }
public string Name { get; set; }
public String Address { get; set; }
}
在BLL中我还有从DAL获取产品并将它们映射到业务对象的方法 - ProductBO:
public class ProductService
{
public List<ProductBO> GetAllProducts()
{
List<ProductBO> productsBO = new List<ProductBO>();
using (var context = NorthwindFactory.CreateContext())
{
List<Product> products = context.Product.ToList();
foreach (var product in products)
{
productsBO.Add(new ProductBO { ID = product.ID, Address = product.Address, Name = product.Name });
}
}
return productsBO;
}
}
现在在控制器的UI项目中,我从BLL调用服务返回List,在视图中我可以使用业务对象ProductBO显示数据。
@model IEnumerable<WebApplication1.BLL.BusinessObjects.ProductBO>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Address)
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Address)
</td>
</tr>
}
</table>
架构方法是否正确?
答案 0 :(得分:1)
您应该在BLL项目中定义POCO(域)对象,因为它们是业务对象。
您的DAL应该引用BLL,而不是相反。
就个人而言,我是Onion architecture的关注者,它将您的域名置于应用程序的中心。您添加的任何图层应仅向内引用,而不向外引用。因此,根据该定义,您的BLL是中心,并没有引用任何内容。添加DAL图层,它只能向内引用,因此它可以引用BLL。 UI层也仅引用BLL,但不引用DAL,因为DAL是实现细节。
答案 1 :(得分:1)
嗯,没有单一正确方法。但我倾向于避免创建一组DAL类。现代ORM允许使用POCO课程。是的,有一些限制(如枚举),但恕我直言,它不值得创建每个业务实体的两个副本和它们之间的映射。所以,我选择了位于业务逻辑组件中的单个POCO实体。实体框架与该实体一起保存并从数据库加载它。没有映射。
表示层不同。通常,您在不同页面上有多个相同实体的表示。您还将使用不同的Data Annotation属性来设置视图模型或某些UIHints的限制。这将使用特定于UI的逻辑污染您的业务实体。您还经常需要显示格式化或修改过的数据,例如FullName而不是Person实体的FirstName和LastName。所以,在这里我不会使用我的POCO业务实体,而是创建视图模型。
使用您的产品样本,此方法将如下所示:
Product
Product
ProductViewModel
,BriefProductViewModel
等。它还负责Product
和视图模型之间的映射。注 - 手动映射非常耗时。我建议你使用一些映射库,比如AutoMapper或ValueInjecter