0

私はビジネスレイヤーにコマンドを送信するレイヤードアプリケーションを持っています(実際には、アプリケーションはncqrsフレームワークに基づいていますが、ここでは重要ではないと思います)。

コマンドは次のようになります:

public class RegisterUserCommand : CommandBase
{
    public string UserName { get; set; }
    public string Email{ get; set; }
    public DateTime RegistrationDate { get; set; }
    public string ApiKey {get; set;} // edit
}

このクラスにはロジックはなく、データのみです。

ユーザーにユーザー名と電子メールを入力してもらい、システムが現在の日付を使用してコマンドを作成するようにします。

間で最高のもの:

  1. RegisterUserCommandに基づいて厳密に型指定されたビューを作成し、ビジネスレイヤーに送信する直前に日付とAPiキーを挿入しますか?

  2. RegisterUserViewModelクラスを作成し、このクラスでビューを作成し、ビュー入力に基づいてコマンドオブジェクトを作成しますか?

私は次のコードを書きました(ソリューションn°2用):

public class RegisterController : Controller
{
    //
    // GET: /Register/

    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(RegisterUserViewModel registrationData)
    {

        var service = NcqrsEnvironment.Get<ICommandService>();
        service.Execute(
            new RegisterUserCommand
            {
                RegistrationDate = DateTime.UtcNow,
                Email= registrationData.Email,
                UserName= registrationData.Name,
                ApiKey = "KeyFromConfigSpecificToCaller" // edit
            }
            );

        return View();
    }


    public class RegisterUserViewModel
    {
        [Required]
        [StringLength(16)]
        public string Name { get; set; }
        [Required]
        [StringLength(64)]
        public string Email{ get; set; }
    }
}

このコードは機能しています...しかし、正しい方法を選択したかどうか疑問に思います...

アドバイスありがとう

[編集]日時が誤解を招くようであるため、(コマンドレイヤーからではなく)Webレイヤーから、サーバー側にも設定する必要がある別のプロパティ「ApiKey」を追加しました。

[編集2] Erikの提案を試して、私が想像した最初のソリューションを実装します。

[HttpPost]
public ActionResult Index(RegisterUserCommand registrationCommand)
{

    var service = NcqrsEnvironment.Get<ICommandService>();
    registrationCommand.RegistrationDate = DateTime.UtcNow;
    registrationCommand.ApiKey = "KeyFromConfigSpecificToCaller";
    service.Execute(
        registrationCommand
        );

    return View();
}

...それは受け入れられますか?

4

3 に答える 3

2

別のViewModelとコマンドがあるオプション#2の方が良いと思います。(ある程度)冗長に見えるかもしれませんが、コマンドは実際にはWebサーバーからコマンドハンドラーへのメッセージです。これらのメッセージは、ViewModelと同じようにフォーマットされていない可能性があります。また、NCQRSをそのまま使用している場合は、コマンドをARメソッドとコンストラクターにマップする必要があります。

少し時間を節約できるかもしれませんが、ViewModelsの後にドメインをモデル化することに夢中になっていると思いますが、そうではないはずです。ViewModelは、ユーザーが体験し、見ているものを反映している必要があります。ドメインはビジネスルールと知識を反映している必要があり、常にビューに反映されているとは限りません。

今はもう少し手間がかかるように思えるかもしれませんが、自分に有利に働き、コマンドをビューモデルから分離してください。後で感謝します。

これがお役に立てば幸いです。幸運を!

于 2011-09-13T01:54:29.120 に答える
1

番号1を使用し、検証にsystem.componentmodel.dataannotations.metadatatypeを使用します。

ここに別のSO質問の例(回答)を作成しました。

これにより、モデルを別のライブラリに保持し、フィールドを検証して、DataAnnotationsを使用した内部/プライベートクラスのようにフィールドを表示できます。私は、データを別のクラスにORMで戻す必要がある一方で、付加価値のないビュー用に完全に別個のクラスを作成することはあまり好きではありません。(ドロップダウンリスト値やデフォルト値などの追加の値がある場合は、それが理にかなっていると思います)。

それ以外の

[HttpPost]
public ActionResult Index(RegisterUserViewModel registrationData)
{

    var service = NcqrsEnvironment.Get<ICommandService>();
    service.Execute(
        new RegisterUserCommand
        {
            RegistrationDate = DateTime.UtcNow,
            Email= registrationData.Email,
            UserName= registrationData.Name,
            ApiKey = "KeyFromConfigSpecificToCaller" // edit
        }
        );

    return View();
}

あなたが持つことができます

[HttpPost]
public ActionResult Index(RegisterUserCommand registrationData)
{

    var service = NcqrsEnvironment.Get<ICommandService>();

    registrationData.ApiKey = "KeyFromConfigSpecificToCaller";

    service.Execute(registrationData);

    return View();
}
于 2011-09-12T14:45:28.023 に答える
1

これをRegisterUserCommandクラスのコンストラクターに入れることをお勧めします。このように、デフォルトの動作は常にDateTime.UtcNowに設定することであり、明示的に設定する必要がある場合は、オブジェクト初期化子に追加するだけです。これは、プロジェクトの他の部分でこのクラスを使用していて、RegistrationDateを明示的に設定するのを忘れた場合にも役立ちます。

public class RegisterUserCommand : CommandBase
{
    public string UserName { get; set; }
    public string Email{ get; set; }
    public DateTime RegistrationDate { get; set; }

    public RegisterUserCommand()
    {
        RegistrationDate = DateTime.UtcNow;
    }
}

そしてコントローラー

public class RegisterController : Controller
{
    //
    // GET: /Register/

    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(RegisterUserViewModel registrationData)
    {

        var service = NcqrsEnvironment.Get<ICommandService>();
        service.Execute(
            new RegisterUserCommand
            {
                Email= registrationData.Email,
                OpenIdIdentifier = registrationData.OpenIdIdentifier
            }
            );

        return View();
    }


    public class RegisterUserViewModel
    {
        [Required]
        [StringLength(16)]
        public string Name { get; set; }
        [Required]
        [StringLength(64)]
        public string Email{ get; set; }
    }
}
于 2011-09-12T14:54:32.703 に答える