N-Tier Architecture : 비즈니스 객체를 저장하기에 가장 좋은 장소?
-
18-09-2019 - |
문제
3 계층 아키텍처 (UI, 비즈니스 및 데이터)가 있다고 가정 해 봅시다. 일반적으로 데이터 액세스 오브젝트를 유지하기 위해 "모델"또는 "공통"이라는 4 번째 프로젝트를 만듭니다. 그리고 다른 각 프로젝트는이 프로젝트를 사용합니다.
이제 데이터 액세스 객체 중 일부에 데이터 프로젝트에 액세스 해야하는 Save () 등과 같은 방법이있는 프로젝트를 진행하고 있습니다. 따라서 데이터 프로젝트에서 모델/공통 프로젝트를 사용하려고 시도하면 순환 참조가있을 것입니다.
이 시나리오에서 데이터 액세스 개체를 유지하기에 가장 좋은 곳은 어디입니까? 데이터 프로젝트 자체 내에 보관할 수는 있지만 데이터 액세스 객체에 대해 알아야 할 UI 프로젝트는 데이터 계층에 액세스해야합니다.
해결책
이것이 제가 프로젝트에서 가지고있는 것입니다.
1.) Application.infrastructure
- 모든 BusinessObjects, Busines Object Collection, Data-Access 클래스 및 내 사용자 지정 속성 및 유틸리티에 대한 기본 클래스 확장 방법, 일반 유효성 검증 프레임 워크. 이것은 최종 .NET 응용 프로그램의 전체 행동 구성을 결정합니다.
2.) Application.Datamodel
- 데이터베이스의 입력 데이터 세트.
- Tableadapters는 내가 필요할 수있는 거래 및 기타 기능을 통합하기 위해 확장되었습니다.
3.) application.dataaccess
- 데이터 액세스 클래스.
- 데이터베이스 작업이 기본 유형 데이터 세트를 사용하여 쿼리되는 실제 장소.
4.) application.domainobjects
- 비즈니스 객체 및 비즈니스 객체 컬렉션.
- 열거.
5.) Application.BusinessLayer
- 프레젠테이션 계층에서 액세스 할 수있는 관리자 클래스를 제공합니다.
- httphandlers.
- 내 자신의 페이지 기본 클래스.
- 더 많은 것들이 여기에 간다 ..
6.) application.webclient 또는 application.windowsclient
- 내 프레젠테이션 계층
- Application.BusinessLayer 및 Application.BusinessObjects에서 참조를 가져옵니다.
Application.businessObjects는 응용 프로그램을 통해 사용되며 Neeed가있을 때마다 모든 레이어를 가로 질러 이동합니다 [application.datamodel 및 applact.infrastructure
모든 쿼리는 application.datamodel 만 정의됩니다.
Application.DataAccess 데이터 액세스 작업의 일부로 비즈니스 오브젝트를 반환하거나 가져옵니다. 비즈니스 객체는 반사 속성의 도움으로 작성됩니다. 각 비즈니스 객체는 데이터베이스의 대상 테이블에 대한 속성 매핑으로 표시되며 비즈니스 객체의 속성에는 각 데이터베이스 테이블에서 Coloumn을 대상으로하는 속성 매핑이 표시됩니다.
내 검증 프레임 워크를 사용하면 지정된 검증 변호사의 도움으로 각 필드를 검증 할 수 있습니다.
내 framrwork는 속성을 크게 사용하여 매핑 및 검증과 같은 대부분의 지루한 작업을 자동화합니다. 또한 프레임 워크에서 새로운 측면으로 새로운 기능을 할 수 있습니다.
샘플 비즈니스 객체는 내 응용 프로그램에서 이와 같이 보입니다.
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)
{
}
}
다른 팁
나는 당신이 당신의 n-tier가 옳다고 생각하지 않습니다. 더 2 계층 시스템을 구축하는 것처럼 들립니다.
실제 3 계층 프로젝트에서는 데이터 계층 만 데이터베이스와 대화 할 수 있습니다. "모델"또는 "공통"프로젝트와 함께 있습니다. 그 프로젝트 ~이다 귀하의 데이터 계층. 그러나 당신이 떠나는 곳은 바로 그 것입니다 뿐 비즈니스 계층은 그들과 대화 할 수 있어야합니다. 프레젠테이션 코드는 데이터 계층 프로젝트와 전혀 이야기 할 수 없습니다.
N-Tier는 3 개 이상의 "계층"이있을 때 발생하지만 동일한 원리 응용 프로그램은 다음과 같습니다. 각 계층은 아래의 사용 방법을 알고 있으며 위의 계층에 대한 API를 제공합니다. 그것. 내 프로젝트에서는 일반적인 프레젠테이션, 비즈니스 및 데이터 계층을 취하고 비즈니스와 데이터 사이에 4 번째 "번역"계층을 제공합니다. 이런 식으로 데이터 계층은 데이터 세트, 데이터 가능 및 Datarow 및 비즈니스 계층과 같은 일반 유형을 반환 할 수 있습니다. 뿐 강력한 비즈니스 객체의 관점에서 작업해야합니다. 번역 계층 뿐 일반 데이터 객체와 강하게 유형 된 객체를 변환합니다. 이런 식으로 전통적인 계층 중 하나에 대한 변화는 다른 계층의 변화를 요구할 가능성이 적습니다.
데이터 계층은 관계형 백엔드를 사용하는 경우 행 및 열 (원하는 경우 타이핑 된 데이터 세트를 사용하는 경우) 측면에서 정보를 저장해야합니다. "비즈니스 오브젝트"는 없습니다.
비즈니스 계층은 "비즈니스 개체"를 사용해야합니다. BusinessObjects 프로젝트를 참조 할 수 있습니다.
요약해서 말하자면:
- UI는 비즈니스 및 비즈니스 객체에 대한 언급을 가지고 있습니다
- 비즈니스는 BusinessObjects 및 데이터에 대한 참조를 가지고 있습니다
도움이 되었기를 바랍니다.
나는 Mappings (ORM)를 저장하는 Server Side 및 CRUD 작업을 노출시키는 해당 DataAccess 서비스 (및 Getall과 같은) 등을 노출시키는 BusinessObjects 프로젝트를 가지고 있습니다.
모델 프로젝트에서 원하는 것을 작성하고 인터페이스하고 데이터 계층에서 해당 정의를 구현하는 것이 좋습니다. 이렇게하면 세 가지 (4 개의?) 프로젝트 모두 구현 방법을 모르고 해당 정의를 사용할 수 있습니다.
제 생각에는 비즈니스 계층만이 데이터 액세스 객체에 대한 지식이 있어야합니다. 자체 비즈니스 규칙 및 논리를 적용하면서 데이터 운영에 사용한 다음 위의 UI 계층에 멍청한 개체 (예 : 데이터 전송 객체)를 반환해야합니다.
당신은 같은 것을 사용할 수 있습니다 automapper 데이터와 비즈니스 객체를 자동으로 매핑하려면
MVC (Front Controller Pattern)를 사용하는 경우 실제로 패턴에 따라 달라지면 모델은 응용 프로그램이 작동하는 데이터 (일반적으로 ORM 도움말)의 도메인 별 표현입니다. 우리는이 클래스에 데이터 프로젝트를 사용합니다. .
모델은 데이터 액세스 오브젝트가 아니므로 데이터 액세스는 다른 프로젝트에서 리포지토리 형태가됩니다. 비즈니스 규칙 및 마지막으로 웹 프로젝트를위한 서비스. 이 접근법에서는 data.dll이 모든 프로젝트에서 참조됩니다. 모델은 전능 한 것과 같습니다.
DATA(Domain Model) -> REPOSITORY(Data Access) -> SERVICE(Business Rules) -> WEB