4

假设我有一个 3 层架构(UI、业务和数据)。通常,我会创建一个名为“Model”或“Common”的第四个项目来保存我的数据访问对象,然后其他每个项目都会使用这个项目。

现在我正在开发一个项目,其中我的一些数据访问对象具有 Save() 等需要访问 Data 项目的方法。因此,如果我尝试在 Data 项目中使用 Model/Common 项目,我会有一个循环引用。

在这种情况下,保存数据访问对象的最佳位置在哪里?我可以将它保存在 Data 项目本身中,但是我的 UI 项目需要了解数据访问对象,需要访问 Data 层,这不好。

4

7 回答 7

8

我认为您的 n 层不太正确。听起来您正在构建更多的 2 层系统。

在真正的 3 层项目中,只允许您的数据层与数据库通信。你的“模型”或“通用”项目就有了。这些项目您的数据层。但是你偏离的地方是允许业务层与他们交谈。根本不应该允许您的演示代码与数据层项目对话。

当你有超过 3 个“层”时,n-Tier 就会出现,但同样的原则适用:每个层只知道如何使用(并且只需要引用)它下面的那个,然后为上面的层提供一个 api它。在我自己的项目中,我采用您的典型演示、业务和数据层,并在业务和数据之间提供第四个“转换”层。这样,数据层可以返回数据集、数据表和数据行等通用类型,而业务层需要针对强类型业务对象工作。转换层在通用数据对象和强类型对象之间进行转换。这样,对传统层之一的更改不太可能需要对另一个层进行更改。

于 2009-12-09T00:04:11.450 回答
2

This is what I have in my project.

1.) Application.Infrastructure

  • Base classes for all businessobjects, busines object collection, data-access classes and my custom attributes and utilities as extension methods, Generic validation framework. This determines overall behavior organization of my final .net application.

2.) Application.DataModel

  • Typed Dataset for the Database.
  • TableAdapters extended to incorporate Transactions and other features I may need.

3.) Application.DataAccess

  • Data access classes.
  • Actual place where Database actions are queried using underlying Typed Dataset.

4.) Application.DomainObjects

  • Business objects and Business object collections.
  • Enums.

5.) Application.BusinessLayer

  • Provides manager classes accessible from Presentation layer.
  • HttpHandlers.
  • My own Page base class.
  • More things go here..

6.) Application.WebClient or Application.WindowsClient

  • My presentation layer
  • Takes references from Application.BusinessLayer and Application.BusinessObjects.

Application.BusinessObjects are used across the application and they travel across all layers whenever neeeded [except Application.DataModel and Application.Infrastructure]

All my queries are defined only Application.DataModel.

Application.DataAccess returns or takes Business objects as part of any data-access operation. Business objects are created with the help of reflection attributes. Each business object is marked with an attribute mapping to target table in database and properties within the business object are marked with attributes mapping to target coloumn in respective data-base table.

My validation framework lets me validate each field with the help of designated ValidationAttribute.

My framrwork heavily uses Attributes to automate most of the tedious tasks like mapping and validation. I can also new feature as new aspect in the framework.

A sample business object would look like this in my application.

User.cs

[TableMapping("Users")]
public class User : EntityBase
{
    #region Constructor(s)
    public AppUser()
    {
        BookCollection = new BookCollection();
    }
    #endregion

    #region Properties

    #region Default Properties - Direct Field Mapping using DataFieldMappingAttribute

    private System.Int32 _UserId;

    private System.String _FirstName;
    private System.String _LastName;
    private System.String _UserName;
    private System.Boolean _IsActive;

    [DataFieldMapping("UserID")]
    [DataObjectFieldAttribute(true, true, false)]
    [NotNullOrEmpty(Message = "UserID From Users Table Is Required.")]
    public override int Id
    {
        get
        {
            return _UserId;
        }
        set
        {
            _UserId = value;
        }
    }

    [DataFieldMapping("UserName")]
    [Searchable]
    [NotNullOrEmpty(Message = "Username Is Required.")]
    public string UserName
    {
        get
        {
            return _UserName;
        }
        set
        {
            _UserName = value;
        }
    }

    [DataFieldMapping("FirstName")]
    [Searchable]
    public string FirstName
    {
        get
        {
            return _FirstName;
        }
        set
        {
            _FirstName = value;
        }
    }

    [DataFieldMapping("LastName")]
    [Searchable]
    public string LastName
    {
        get
        {
            return _LastName;
        }
        set
        {
            _LastName = value;
        }
    }

    [DataFieldMapping("IsActive")]
    public bool IsActive
    {
        get
        {
            return _IsActive;
        }
        set
        {
            _IsActive = value;
        }
    }

    #region One-To-Many Mappings
    public BookCollection Books { get; set; }

    #endregion

    #region Derived Properties
    public string FullName { get { return this.FirstName + " " + this.LastName; } }

    #endregion

    #endregion

    public override bool Validate()
    {
        bool baseValid = base.Validate();
        bool localValid = Books.Validate();
        return baseValid && localValid;
    }
}

BookCollection.cs

/// <summary>
/// The BookCollection class is designed to work with lists of instances of Book.
/// </summary>
public class BookCollection : EntityCollectionBase<Book>
{
    /// <summary>
    /// Initializes a new instance of the BookCollection class.
    /// </summary>
    public BookCollection()
    {
    }

    /// <summary>
    /// Initializes a new instance of the BookCollection class.
    /// </summary>
    public BookCollection (IList<Book> initialList)
        : base(initialList)
    {
    }
}
于 2009-12-09T06:33:33.167 回答
1

我有一个 BusinessObjects 项目,服务器端存储映射(ORM)和相应的 DataAccess 服务,在它们上公开 CRUD 操作(以及其他也像 GetAll)等。

于 2009-12-09T00:20:53.433 回答
1

如果您使用的是关系后端,数据层应该以行和列的形式存储信息(如果您愿意,可以使用类型化的数据集)。没有“业务对象”。

业务层应该使用您的“业务对象”。它可以引用 BusinessObjects 项目。

总之:

  • UI 引用了 Business 和 BusinessObjects
  • 业务有对业务对象和数据的引用

希望这可以帮助。

于 2009-12-08T23:45:41.493 回答
0

我建议在模型项目中创建和接口您想要的内容,并在数据层中实现该定义。这样所有三个(四个?)项目都可以使用该定义,而不知道它是如何实现的。

于 2009-12-08T23:51:13.857 回答
0

在我看来,只有业务层应该了解数据访问对象。它应该在应用自己的业务规则和逻辑的同时将它们用于数据操作,然后将哑对象(例如数据传输对象)返回给上面的 UI 层。

您可以使用AutoMapper 之类的东西在数据和业务对象之间自动映射。

于 2009-12-08T23:57:58.307 回答
0

它真的取决于模式,如果您使用 MVC(前端控制器模式),模型是应用程序操作的数据的特定域表示(通常是 ORM 帮助)我们为此类使用 DATA 项目.

模型不是数据访问对象,因此数据访问以不同项目中的存储库的形式出现。业务规则服务,最后是 Web 项目。在这种方法中,Data.dll 在所有项目中都被引用。模型就像无所不在。

DATA(Domain Model) -> REPOSITORY(Data Access) -> SERVICE(Business Rules) -> WEB
于 2009-12-09T00:11:00.863 回答