0

現在のプロジェクトに適したアーキテクチャを取得するのに苦労しています。ソフトウェア エンジニアリングのベスト プラクティス (DI、単体テストなど) を使用しようとして本格的な n 層アプリを設計するのは初めてです。私のプロジェクトは Onion アーキテクチャを使用しています。

私は4つのレイヤーを持っています

  1. コア層: ビジネス オブジェクトを保持しています。ここには、ビジネス エンティティをメソッドで表すクラスがあります。これらのオブジェクトの一部には、サービス インターフェイスへの参照があります。

  2. DAL (データ アクセス) レイヤー : POCO オブジェクトを定義し、コア レイヤーで定義されたリポジトリ インターフェイスを実装します。このレイヤーでは、POCOs オブジェクトを DAL から Core のビジネス オブジェクトに変換する役割を持つ大きなユーティリティ クラスを設計するのは良い考えだと思いました。

  3. サービス層 : コアで定義されたサービス インターフェイスを実装します。この層の役割は、DAL で定義されたリポジトリへのアクセスを提供することです。このレイヤーは役に立たないと主に信じていたので、コアレイヤーで定義されているリポジトリインターフェイスを直接使用しました。しかし、非常に長いインスタンス化コードの作成に数週間費やした後、コンストラクターに 5 ~ 6 個の IRepository パラメーターを使用させた後、Service Layer の要点を理解しました。

  4. プレゼンテーション層。ここで特に言うことはありませんが、このレイヤーで依存性注入を構成することを除いて (私は Ninject を使用しています)。

アーキテクチャを変更し、少なくとも 3 回はコードを書き直しました。これは、コードに何か問題があることに何度も遭遇したためです。(長いパラメーター リストを持つ長いコンストラクターのようなもの)。幸いなことに、私は文献に見られるさまざまなコーディング パターンの要点を理解しています。

しかし、私は DI で周期的な依存関係に遭遇したばかりで、私の DAL2Core ヘルパーが良いアイデアであったかどうか真剣に考えています...

このヘルパーのおかげで、次のようなコードを書くことができます:

        DAL.Point p = DAL2Core.PointConverter(point); // point is a Core Object
        context.Points.Add(p);
        context.SaveChanges();

これにより、コードの冗長性が少し軽減されます。次に、DAL で定義された各リポジトリには、独自の DAL2Core メンバーがあります。

private IDAL2CoreHelper DAL2Core;

そして、それを Repository コンストラクターから注入します。

DAL2Core クラス自体は少し面倒です... まず、すべてのリポジトリとすべてのプロセッサ (サービス層) のプロパティがあります。プロセッサが存在する理由は、コア オブジェクトにプロセッサの依存関係を挿入する必要があるためです。説明のために、DAL2Core ユーティリティ クラスで参照されているリポジトリとプロセッサの一部を以下に示します。

    [Inject]
    private Core.IUserRepository UserRepository{ get; set; }
    [Inject]
    private Core.IPointsRepository PointsRepository { get; set; }


...

    [Inject]
    private Core.IUserProcessor UserProcessor{ get; set; }
    [Inject]
    private Core.IPointsProcessor CoursProcessor { get; set; }

(DAL2Core ヘルパーはリポジトリで必要とされるため、コンストラクター インジェクションは循環的な依存関係を引き起こします)

そして、このクラスには次のような単純なメソッドがたくさんあります。

public Core.User UserConverter(DAL.User u)
    {
        Core.User user = new Core.User(UserProcessor);   
        user.FirstName= u.FirstName;
        user.Name= u.Name;
        user.ID = u.ID;
        user.Phone= u.Phone;
        user.Email= u.Email;
        user.Birthday= u.Birthday;
        user.Photo = u.Photo;
        return user;
    }

このクラスは 600 百行のようなものです。考えてみると、多くの場合、DAL2Core 変換コードは 1 か所からしか呼び出されないため、あまりコードを保存していないことに気付きました。おそらく、このコードはリポジトリに残した方がよいのではないでしょうか? そして、最大の問題は、このヘルパーをリポジトリ クラスから切り離すことにしたため、Ninject によって周期的な依存例外がスローされることです。

私が試したデザインについてどう思いますか、それは良い/一般的な方法ですか? そして、この DAL2Core 変換をコードのにおいを気にせずにスマートかつ効率的に実行するにはどうすればよいでしょうか。私はこのアーキテクチャの問題を解決することを本当に楽しみにしています。私はこの 3 週間、配管とアーキテクチャの問題に対処し、そのプロジェクトを実際には進めていませんでした。私は非常に遅くなってきています。しかし、私は本当に高品質のコードを作成したいと考えています。多くのファクトリなどを使用して、やり過ぎに見えるアーキテクチャソリューションを避けたいだけです...しかし、この感覚は、私からの理解の欠如から来る場合があることを認めます(サービスレイヤーの場合のように)。

よろしくお願いいたします。

4

1 に答える 1