web-dev-qa-db-ja.com

UIレイヤーはどのようにユーザー入力をBLレイヤーに渡す必要がありますか?

私はn層アプリケーションを構築しています。UI、BL、DAL、およびエンティティ(POCOから作成)のプロジェクトがあります。 (すべてのプロジェクトにはエンティティへの参照があります)。

私の質問は-BLメソッドに渡された文字列の束としてユーザー入力をUIからBLにどのように渡すか、そしてBLはパラメーターからオブジェクトを構築するか、またはUI submit_function内でオブジェクトを構築して送信する必要があるかパラメータとしてのオブジェクト?

編集:私はn-tier application、しかし私が実際に意味したのは単なるレイヤーでした。

7
BornToCode

how should I pass user input from the UI to the BL, as a bunch of strings passed to the BL method and the BL will build the object from the parameters, or should I build the objects inside the UI submit_function and send objects as parameters?

オブジェクトをパラメーターとして送信することをお勧めします。利点:

  1. 今後、SL/BLレイヤーで使用するためにさらにパラメーターが必要になった場合は、サービス、ビジネス、DAOレイヤーのメソッドシグネチャを変更せずにそれらを含めることができます。
  2. データを含むオブジェクトは、レイヤーで再利用できます。 BLが同じオブジェクトタイプを返す場合、その属性を変更することにより、初期化されたオブジェクトを再利用できます。
  3. より読みやすいコード。 10〜20個のパラメーターを渡す必要があると想定します。個別のフィールドにすべてを渡すのではなく、パラメーターとして単一のオブジェクトをお勧めします。

短所:

  1. ロード時間とメモリを消費するオブジェクトを初期化する必要があります。
  2. オブジェクト属性を準備してフェッチするには、コード行を使用する必要があります。
1
Satish Pandey

理想的な(サービス指向の多層)の世界では、UIはデータコントラクトとサービスファサードを通じてビジネスレイヤーと通信する必要があります。 UIは、実際のビジネスレイヤー、またはビジネスレイヤーが使用するエンティティとメソッドについて何も知る必要はありません。したがって、UIとサービスファサードはデータコントラクト定義を共有します(これらは単純なコンテナークラスまたはXSDの場合があります)。 UIは、データコントラクトを使用して公開されたサービスファサードのメソッドを呼び出し、ビジネスデータをやり取りします。データコントラクトをBLエンティティに変換し、サービスの実行に必要なBLメソッドを呼び出すのは、サービスファサード次第です。

どうして?

  1. これにより、意図的かつ明示的に公開されたサービスとコントラクトに基づいて、UIとBLの間にクリーンなインターフェイスが作成されます。あるレイヤーでの変更は、別のレイヤーに影響を与える必要はありません。
  2. 自動化された単体テストの作成に役立ちます。サービスファサードのモック実装でUIをテストすることもできます。
  3. それはよりサービスに焦点を当てたアプローチを推進します。一連の個別のメソッド呼び出しではなく、公開されるサービスです。 「うまくいけば」UIとBL間の呼び出しの数を制限します。
7
Stimy

ここでは、通常、n層アプリケーションを構築する方法を示します。この場合は、MVC Webアプリケーションプロジェクトを使用します。

通常、次のように呼ばれるクラスライブラリ:ProjectFoo.Domain

ここで、データにアクセスするための抽象的なリポジトリを作成します。例えば:

public interface IAccountRepository
{
    IEnumerable<Account> FindAll();
}

ここでも具体的な実装を作成します。1つは実際のデータベースにアクセスし、もう1つはモック情報を返します。

public class DbAccountRepository : IAccountRepository
{
    public IEnumerable<Account> FindAll()
    {
        DbConnector db = new DbConnector();
        return db.Accounts;
    }
}

public class MockAccountRepository : IAccountRepository
{
    public IEnumerable<Account> FindAll()
    {
        return new List<Account>(){
            new Account { Name = "Sergio", Age = 22 },
            new Account { Name = "Brad", Age = 42 },
            new Account { Name = "Chelios", Age = 32 },
        }
    }
}

次に、私のUIプロジェクトでは、通常ProjectFoo.WebUI

コントローラーの内部では、依存関係注入を使用して、私が取り組んでいる実装を整理します。

public class AccountController 
{
    IAccountRepository _accountRepository = new IAccountRepository();

    public AccountController(IAccountRepository accountRepository)
    { 
        _accountRepository = accountRepository;
    }

    public ActionResult Index()
    {
        // Magic! We don't need to know what exactly we're working against.
        var accounts = accountRepository.FindAll();
    }
}

さて、あなたの質問、How to pass user input from the UI to the BL?

私のインターフェースは次のように書かれています:

public class DbAccountRepository : IAccountRepository
{
    // Notice this is the entity object type.
    public void AddAccount(Account account)
    {
        db.AddToAccounts(account);
        db.SaveChanges();
    }
}

ユーザー入力を取得、整形、検証し、シンプルなPOCOオブジェクト内に収めます。サニタイズされて正しく機能していることを確認したら、AutoMapperなどを使用してエンティティオブジェクトにマップし、完全に読み込まれたオブジェクトをチェーンに沿ってリポジトリに渡します。 。

質問がある場合や何かがよくわからない場合はお知らせください。

1
sergserg

サービスはインターフェースです。メソッド/関数はインターフェースです。サービスは、論理層ではなく、物理層への変更を克服するためのものである必要があります。

複数の物理ネットワークに分割され、それ自体と通信する単一の論理層を持つこともできます。そのため、サービスは論理層を分割するための固定線であってはなりません。物理的な分割用です。

UIとBLLが同じボックスでも異なるボックスでも柔軟に機能するようにしたい場合は、サービスを利用してください。それ以外の場合は、bllへの直接メソッド呼び出しを行うことは罪ではありません。

1
ttttttt