私はビジュアルスタジオで働いています。ソリューションには、次の4つのプロジェクトが含まれています。
[〜#〜]ダル[〜#〜]
エンティティフレームワーク+リポジトリパターンで動作します。 DBクラス+リポジトリが含まれています。
[〜#〜] bll [〜#〜]
DTOクラスとサービスが含まれています。サービスは、DTOクラスをDBクラスにマップします。 DALプロジェクトを参照します。
IMessageRepository messageRepo;
public MessageService()
{
this.messageRepo = new MessageRepository();
AutoMapper.Mapper.Initialize(cfg => cfg.AddProfile<AutoMapperProfile>());
}
public MessageService(IMessageRepository repo)
{
this.messageRepo = repo;
AutoMapper.Mapper.Initialize(cfg => cfg.AddProfile<AutoMapperProfile>());
}
public List<DTO.Message> GetAll()
{
List<DTO.Message> messages = ((System.Linq.IQueryable<DAL.Message>)messageRepo.GetAll()).ProjectTo<DTO.Message>().ToList();
return messages;
}
プレゼンテーション
BLLプロジェクトとEntityFramework.SqlServer.dllを参照します。
MessageService ms = new MessageService();
List<Message> messages = ms.GetAll();
ボーナス:ユニットテスト
BLLプロジェクトとDALプロジェクトを参照します(リポジトリをモックします)。
[TestClass]
public class MessageServiceTest
{
Mock<IMessageRepository> messageRepo;
MessageService messageService;
[TestInitialize]
public void SetUp()
{
// Create a new mock of the repository
messageRepo = new Mock<IMessageRepository>();
// Set up the mock for the repository
messageRepo.Setup(x => x.GetAll()).Returns((new List<DAL.Message>
{
new DAL.Message { Id = 1, Content = "Hello world!", Date = DateTime.Now },
new DAL.Message { Id = 2, Content = "I <3 U!", Date = DateTime.Now }
}).AsQueryable());
// Create the service and inject the repository into the service
messageService = new MessageService(messageRepo.Object);
}
[TestMethod]
public void TestGetAll()
{
// Act
var messages = messageService.GetAll();
// Assert
Assert.AreEqual(2, messages.Count, "The messages count is not correct");
}
}
ソフトウェアアーキテクチャは初めてです。このアーキテクチャーについてどう思いますか?何か改善はありますか?
サービスクラスは冗長です。リポジトリは、EFオブジェクトではなく「実際の」オブジェクトを返す必要があります。
リポジトリ内ですべての検索とマッピングを行います。
ユニットテストでは、モックセットアップ以外は何もテストしません。マッピングが失敗することさえありますか?
リポジトリの単体テストをスキップして、統合テストに進みます。あなたが最も多くのバグを取得するSQLとオブジェクトの作成として。
Entity Frameworkには、スケールアップ時にlotの問題があります。それをリポジトリの背後に隠すと、IQueryable、遅延読み込み、自動作成、クラスへのマッピングなどの(いわゆる)メリットが失われます。
私はそれを取り出し、SqlClientとDataReaderを使用して手動でDTOを設定します。
DTOがモデルであるかどうか、またはDTOを使用して入力するロジックを備えた他のモデルがあるかどうかは明確ではありません。または、モデルを別のプロジェクトに入れるかどうか。 (私がお勧めします)
また、実際にデータベースがセットアップされたデータベースプロジェクトが必要です。多くの場合、これをスキップし、データベースを手動で作成してから、新しいインスタンスをデプロイしたり、テーブルなどを追加したりするときに、ソース管理とデプロイメントパスがありません。
全体的に3層の設計について尋ねますが、データ層だけを示しています。
PSすべてのリポジトリメソッドを非同期タスクに変更します<>