UI をデータ アクセスから分離することに関して、ascx ユーザー コントロールを設計するための「ベスト プラクティス」は何ですか? ユーザー コントロールは、プロジェクトのように 3 層アーキテクチャを使用する必要がありますか?それとも、ユーザー コントロール内からデータ アクセスを実行できますか?
5 に答える
ユーザー コントロールからデータベースにアクセスしないでください。データベースにアクセスするためのクラスを作成し、アプリケーション内のすべてがそのクラスを使用する必要があります。基本的に、クラス内のメソッドはストアド プロシージャ呼び出しのラッパーになりますが、アプリケーション (したがってユーザー コントロール) が認識するのは、必要なパラメーターを持つメソッドだけです。アプリケーションの観点から見たデータベースの知識はありません。これにより、アプリケーションを変更せずにデータベースに変更を加えることができます。
このリンクはあなたを助けるかもしれません:
プロジェクトがどれほど単純であろうと複雑であろうと、少なくとも、すべてをプレゼンテーション層、ビジネス層、およびデータ層に分離する必要があります。任意の時点で、3 つのうちのいずれかが、他のものに影響を与えることなく変更される可能性があります。
ユーザーコントロールはプレゼンテーションレイヤーの一部であり、データとユーザーアクションをビジネスレイヤーに提供し、ビジネスレイヤーはデータとそれらのアクションを解釈して決定を下します。必要に応じて、ビジネス層はデータ層を呼び出します。データ層は、データベース/ソース ファイルとのすべての通信を処理します。
3つを分離して別々に保つことはそれほど難しくありません。
ある種のビジネスレイヤーからデータにアクセスすることをお勧めします。UI がデータベースに直接アクセスすることはありません。
- アクセス ルールが変更された場合はどうなりますか?
- ストレージが変更された場合はどうなりますか?
- すべての UI コントロールがビジネス ルールを適用できることを確認できますか?
- 等
少なくとも、データとその他すべての 2 層ソリューションが必要です。より複雑なプロジェクトでは、それ以外のすべてを取り込んで、プレゼンテーション、ロジック、データに抽象化する必要があります。データは、データ アクセス レイヤーとデータ モデル レイヤーに分離することもできます。
これが私のプロジェクトにあるものです。
1.)アプリケーション.インフラストラクチャ
- すべてのビジネス オブジェクトの基本クラス、ビジネス オブジェクト コレクション、データ アクセス クラス、および拡張メソッドとしてのカスタム属性とユーティリティ、ジェネリック検証フレームワーク。これにより、最終的な .net アプリケーションの全体的な動作構成が決まります。
2.)アプリケーション.データモデル
- データベースの型付きデータセット。
- TableAdapters を拡張して、必要なトランザクションやその他の機能を組み込むことができます。
3.) Application.DataAccess
- データ アクセス クラス。
- 基礎となる型指定されたデータセットを使用してデータベース アクションがクエリされる実際の場所。
4.) Application.DomainObjects
- ビジネス オブジェクトとビジネス オブジェクト コレクション。
- 列挙型。
5.) Application.BusinessLayer
- プレゼンテーション層からアクセスできるマネージャー クラスを提供します。
- HttpHandlers。
- 私自身のページ基本クラス。
- より多くのものはここに行きます..
6.) Application.WebClientまたはApplication.WindowsClient
- 私のプレゼンテーション層
- Application.BusinessLayer および Application.BusinessObjects から参照を取得します。
Application.BusinessObjects はアプリケーション全体で使用され、必要に応じてすべてのレイヤーを移動します [Application.DataModel と Application.Infrastructure を除く]
私のすべてのクエリは、Application.DataModel のみで定義されています。
Application.DataAccess は、データ アクセス操作の一部としてビジネス オブジェクトを取得または取得します。ビジネス オブジェクトは、リフレクション属性を使用して作成されます。各ビジネス オブジェクトは、データベース内のターゲット テーブルへの属性マッピングでマークされ、ビジネス オブジェクト内のプロパティは、それぞれのデータベース テーブル内のターゲット列への属性マッピングでマークされます。
私の検証フレームワークでは、指定された ValidationAttribute を使用して各フィールドを検証できます。
私のフレームワークでは、属性を多用して、マッピングや検証などの面倒なタスクのほとんどを自動化しています。フレームワークの新しい側面として新しい機能を追加することもできます。
サンプル ビジネス オブジェクトは、私のアプリケーションでは次のようになります。
ユーザー.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)
{
}
}