JavaScriptのモジュール性、サーバーベースのMVCおよびビジネスリアリティ


32

これは非常に広範な質問であることを理解していますが、この問題のさまざまな側面を個別に扱っており、すべての概念と技術をまとめるのに苦労しています。

答えには次のテクノロジーを含めるように指定したいと思います。

  • C#
  • MVC 3 w / Razor
  • Javascript w / jQuery

それ以上のもの(Backbone.jsEntity Frameworkなど)は、次の質問への回答に役立つ場合、提案として歓迎します。

上記のテクノロジーを使用して、スケーラビリティとリッチで高速でクリーンなUIを作成する能力を維持しながら、コードとロジックを整理するための最適な戦略は何ですか?

理想的には、ビジネス/企業環境で展開されているソリューションに焦点を当てるべきです。その際、上記の技術リストは変更されないため、「現在使用しているyyyの代わりにxxxを使用する必要があります」というソリューションを提供しないでください。

バックグラウンド

私は毎日jQueryを使用しており、ASP.NETのMVCを採用しており、C#で長い間作業しています。そのため、これらのテクノロジーに関する中級から上級の知識を前提としたソリューションを提示できます。

質問をより小さな部分に整理して、より簡単に回答できるようにします。

1.プロジェクトの構造

ASP.NET MVC(Visual Studio 2010)で作業していることを考えると、このタイプのアプリケーションのメインレイアウトをある程度受け入れられるディレクトリ構造ソリューションが必要です。ブランチのようなものだと思いますが、各フォルダーに含まれる内容と、アプリの他の領域との連携についてもう少し詳しく説明します。

2.データアクセス

APIタイプの構造で、できる限りデータアクセスをモジュール化したいと思います。あなたはPOCOオブジェクト(多くの仮定することができUserUserGroupCustomerOrderHeaderOrderDetails、など)だけでなく、データ集約型SQLと慎重なUIのレンダリングを必要とするいくつかの複雑なレポートがあるでしょう。 EF + LINQは前者にとっては素晴らしいですが、後者にとってはそれほどではありません。私は、両方のシナリオに適合すると思われるものを、過度に複雑または過度に単純にすることなく見つけられません。

3.クライアント側のコード編成とUIレンダリング

ほとんどの開発者が最初にjQueryを採用したように、どこに行く必要があるとしてもコードをまとめ上げるというtrapに陥りましたが、すぐにそれが積み重なってくなりました。以来、飛躍的に進歩していますが、コードを繰り返し実行せずにコードをモジュール化し、UIのさまざまな部分を操作するのに苦労しています。

例として、私が書くかもしれない典型的なコードは次のようになります。気になることはコメントしました(それ以降、遅延AJAX呼び出しの使用に変更し、実際のデータ要求をDOM操作から分離していることに注意してください):

$('#doSomethingDangerous').click(function () {
    // maybe confirm something first
    if (confirm('Are you sure you want to do this?')) {   

        // show a spinner?  something global would be preferred so I don't have to repeat this on every page 
        $('#loading').show();  

        // maybe the page should notify the user of what's going on in addition to the dialog?
        $('#results').show().html('<h2>Please wait, this may take a while...</h2>');  

        $.ajax({
            url: 'blah/DoDangerousThing',
            success: function (data) {                     
                // The results will be loaded to the DOM obviously, is there a better way to pull this type of specific code out of the data access calls?
                $('#results').empty();
                $('#results').append('<b>' + data.length + '</b> users were affected by this dangerous activity');
                $('#results').append('<ul>');

                // I've recently started to use jQuery templates for this sort of logic, is that the way to go?
                $(data).each(function (i, user) {
                    $('#results').append('<li>' + user.Username + '</li>');
                });                    
                $('#results').append('</ul>');

                // Need to hide the spinner, again would prefer to have this done elsewhere
                $('#loading').hide();
            }
        });
    }
});

一般的な質問

  • クライアントMVCとサーバーMVCの違い 私のプロジェクトはすでにサーバー側のMVC構造になっているので、Backbone.jsが提供するようなクライアントMVCがまだ必要ですか?
  • Javascriptファイルを各オブジェクト(などOrderHeader.js)ごとに作成し、ビルド中に縮小/マージする必要がありますか?またはOrder.jsOrderHeader, OrderDetails, Reportsなどのためのロジックを持っているだけが必要ですか?
  • 複雑なクエリはどのように処理する必要がありますか?現在、私の主要な理論は/Reports/Orders-By-Date/それらの線に沿ったものであり、カスタムデータセット(またはViewModel)をRazorビューにレンダリングするカスタムSQLクエリを使用しています。しかし、ページング、ソートなどはどうですか?これはクライアント側またはサーバー側で行う方が良いですか?(より大きなデータセット-2〜3秒のSQLクエリを想定)
  • MicrosoftのProject Silkを読みました。これは良い方法ですか?Backbone.jsまたは他の製品と比較してどうですか?
  • 私はN層アーキテクチャに非常に慣れていますが、これらの概念はそれを窓からいくらか投げ出しますか?MVCは、以前はフロントエンドまたはトップティアであったミニNティアセクションの束のようです。

繰り返しますが、具体的な答えは、より良いものになります。 私はたくさんの高レベルのドキュメントと例を読みましたが、それを実際の例に翻訳することよりよく理解しようとしています


2
あなたはこの質問に多くの努力を注ぎましたが、それは私にはStackoverflowの質問のようには見えません。おそらくプログラマーのstackexchangeがより適しているでしょう。
とがった

3
私はそれが興味深いトピックであることには同意しませんが、Stackoverflowは客観的な質問に関するものであると思われます。この質問のようなものは、基本的には「意見、討論、議論、投票、または拡張討論を求める可能性が高い」質問のポスターの子です。
とがった

8
私は彼らの事業を静かに奪いながら、彼らが決して起こらなかった何かのためにあまりにも長い計画を立てたので、常に最大規模を計画している人々のキャンプがあります。
ジェイソンセブリング

1
@Pointyは、これがプログラマスタックに属していることに同意します。あなたの質問はとても興味深いです。私はいつもアドバイスを探しているので、私はそれを続けます。しかし、それは客観的な問題ではなく、優先的な議論で終わるだけです。いつものように、あなたの状況に最適なことをしてください...私たちはあなたのネットワーク構造、クライアント数、トラフィック統計、ビルドプロセスについて何も知りません...だから質問はあまりにも曖昧です...私が知っているのはすべてですシルクを避けてください。;)
one.beat.consumer

1
この質問は、「過度に広範」であり、したがって「実際の質問ではない」というまさにその定義に適合します。どちらかといえば、個々の質問は、若干の背景を持つ個々の質問として行われるべきです(多すぎると、人々は「本当の質問ではない」とフラグを立てます)。しかし、注意してください、あなたが尋ねている個々の質問の多くは、おそらくそれ自体で「建設的ではない」というフラグが立てられるので、私はあなたがそれらの質問をする方法に注意します。
casperOne

回答:


10

私の友人、TerryR、あなたと私は飲み物を飲むべきです。同様の問題がいくつかあります。

1.プロジェクトの構造: MVCアプリのフォルダー構造には、何かが残されているというEduardoに同意します。標準のコントローラー、モデル、およびビューのフォルダーがあります。ただし、Viewsフォルダーは、コントローラーごとに異なるフォルダーと、共有フォルダーに分割されます。また、各Views / ControllerNameまたはViews / Sharedは、EditorTemplatesとDisplayTemplatesに分割できます。ただし、Modelsフォルダーの整理方法を決定できます(サブフォルダーと追加の名前空間宣言の有無にかかわらず実行できます)。

各エリアのコントローラー、モデル、ビューのフォルダー構造を複製するエリアを使用することは禁じられています。

/Areas
    /Area1Name
        /Controllers
            FirstController.cs
            SecondController.cs
            ThirdController.cs
        /Models
            (can organize all in here or in separate folders / namespaces)
        /Views
            /First
                /DisplayTemplates
                    WidgetAbc.cshtml <-- to be used by views in Views/First
                /EditorTemplates
                    WidgetAbc.cshtml <-- to be used by views in Views/First
                PartialViewAbc.cshtml <-- to be used by FirstController
            /Second
                PartialViewDef.cshtml <-- to be used by SecondController
            /Third
                PartialViewMno.cshtml <-- to be used by ThirdController
            /Shared
                /DisplayTemplates
                    WidgetXyz.cshtml <-- to be used by any view in Area1
                /EditorTemplates
                    WidgetXyz.cshtml <-- to be used by any view in Area1
                PartialViewXyz.cshtml <-- to be used anywhere in Area1
            _ViewStart.cshtml <-- area needs its own _ViewStart.cshtml
            Web.config <-- put custom HTML Helper namespaces in here
        Area1NameRegistration.cs <-- define routes for area1 here
    /Area2Name
        /Controllers
        /Models
        /Views
        Area2NameRegistration.cs <-- define routes for area2 here

/Controllers
    AccountController.cs
    HomeController.cs
/Models
/Views
    /Account
        /DisplayTemplates
            WidgetGhi.cshtml <-- to be used views in Views/Account
        /EditorTemplates
            WidgetGhi.cshtml <-- to be used views in Views/Account
        PartialViewGhi.cshtml <-- to be used by AccountController
    /Home
        (same pattern as Account, views & templates are controller-specific)
    /Shared
        /DisplayTemplates 
            EmailAddress.cshtml <-- to be used by any view in any area
            Time.cshtml <-- to be used by any view in any area
            Url.cshtml <-- to be used by any view in any area
        /EditorTemplates
            EmailAddress.cshtml <-- to be used by any view in any area
            Time.cshtml <-- to be used by any view in any area
            Url.cshtml <-- to be used by any view in any area
        _Layout.cshtml <-- master layout page with sections
        Error.cshtml <-- custom page to show if unhandled exception occurs
    _ViewStart.cshtml <-- won't be used automatically in an area
    Web.config <-- put custom HTML Helper namespaces in here

これは、WidgetControllerのようなものを使用している場合、他のフォルダーを調べて、関連するWidgetViewModels、WidgetViews、WidgetEditorTemplates、WidgetDisplayTemplatesなどを見つける必要があることを意味します。これらのMVC規則。モデル、コントローラー、ビューを同じフォルダーに、ただし名前空間が異なる限り、ReSharperを使用しているため、これを避けています。クラスが置かれているフォルダーと一致しない名前空間に波線を付けます。このR#機能をオフにすることはできますが、プロジェクトの他の部分では役立ちます。

クラス以外のファイルの場合、MVCはすぐにコンテンツとスクリプトを提供します。規約に従うために、これらの場所にすべての静的/コンパイルされていないファイルを保持するようにします。テーマ(画像やCSS)を使用するjsライブラリを組み込むときはいつでも、テーマファイルはすべて/ contentの下のどこかに移動します。スクリプトについては、すべてを直接/ scriptsに入れます。もともとこれはVSからJSインテリセンスを取得することでしたが、/ scriptsの配置に関係なくR#からJSインテリセンスを取得するようになったので、それから逸脱してスクリプトをフォルダーごとに分けて整理しやすくしたと思います。ReSharperを使用していますか?純金のIMOです。

リファクタリングに大いに役立つもう1つの小さな金はT4MVCです。これを使用することで、エリア名、コントローラー名、アクション名、さらにはコンテンツやスクリプトのファイルの文字列パスを入力する必要がありません。T4MVCは、すべてのマジックストリングを強力に入力します。T4MVCを使用している場合、プロジェクト構造がそれほど重要ではない方法の小さなサンプルを次に示します。

// no more magic strings in route definitions
context.MapRoutes(null,
    new[] { string.Empty, "features", "features/{version}" },
    new
    {
        area = MVC.PreviewArea.Name,
        controller = MVC.PreviewArea.Features.Name,
        action = MVC.PreviewArea.Features.ActionNames.ForPreview,
        version = "december-2011-preview-1",
    },
    new { httpMethod = new HttpMethodConstraint("GET") }
);

@* T4MVC renders .min.js script versions when project is targeted for release *@
<link href="@Url.Content(Links.content.Site_css)?r=201112B" rel="stylesheet" />
<script src="@Url.Content(Links.scripts.jquery_1_7_1_js)" type="text/javascript">
</script>

@* render a route URL as if you were calling an action method directly *@
<a href="@Url.Action(MVC.MyAreaName.MyControllerName.MyActionName
    (Model.SomeId))">@Html.DisplayFor(m => m.SomeText)</a>

// call action redirects as if you were executing an action method
return RedirectToAction(MVC.Area.MyController.DoSomething(obj1.Prop, null));

2.データアクセス: PetaPocoの経験はありませんが、チェックする価値があると確信しています。複雑なレポートについて、SQL Server Reportingサービスを検討しましたか?または、別のデータベースで実行していますか?申し訳ありませんが、正確に何を求めているのか明確ではありません。EF + LINQを使用しますが、ドメインクラスでレポートを生成する方法に関する特定の知識も提供します。したがって、コントローラー呼び出しリポジトリーを直接持つ代わりに、コントローラー呼び出しドメインサービス呼び出しリポジトリーがあります。アドホックレポートの場合、SQL Reporting Servicesを使用しますが、これも完璧ではありませんが、ユーザーはデータをExcelに簡単に取り込むことができることを望んでおり、SSRSによって簡単になります。

3.クライアント側のコード編成とUIレンダリング:ここで、いくつかのヘルプを提供できると思います。MVCの控えめな検証と控えめなAJAXの本からページを取ります。このことを考慮:

<img id="loading_spinner" src="/path/to/img" style="display:none;" />
<h2 id="loading_results" style="display:none;">
    Please wait, this may take a while...
</h2>
<div id="results">
</div>
<input id="doSomethingDangerous" class="u-std-ajax" 
    type="button" value="I'm feeling lucky" 
    data-myapp-confirm="Are you sure you want to do this?"
    data-myapp-show="loading_spinner,loading_results" 
    data-myapp-href="blah/DoDangerousThing" />

今のところajax成功関数を無視します(これについては後で説明します)。一部のアクションについては、単一のスクリプトで逃げることができます。

$('.u-std-ajax').click(function () {
    // maybe confirm something first
    var clicked = this;
    var confirmMessage = $(clicked).data('myapp-confirm');
    if (confirmMessage && !confirm(confirmMessage )) { return; } 

    // show a spinner?  something global would be preferred so 
    // I dont have to repeat this on every page 
    // maybe the page should notify the user of what's going on 
    // in addition to the dialog?
    var show = $(clicked).data('myapp-show');
    if (show) {
        var i, showIds = show.split(',');
        for (i = 0; i < showIds.length; i++) {
            $('#' + showIds[i]).show();
        }
    }

    var url = $(clicked).data('myapp-href');
    if (url) {
        $.ajax({
            url: url,
            complete: function () {                     
                // Need to hide the spinner, again would prefer to 
                // have this done elsewhere
                if (show) {
                    for (i = 0; i < showIds.length; i++) {
                        $('#' + showIds[i]).hide();
                    }
                }
            }
        });
    }
});

上記のコードは確認を処理し、スピナーを表示し、待機メッセージを表示し、ajax呼び出しの完了後にスピナー/待機メッセージを非表示にします。控えめなライブラリなど、data- *属性を使用して動作を構成します。

一般的な質問

-クライアントMVCとサーバーMVCの違い コントローラがJSONを返しているように見えるため、成功関数で実行したアクションをライブラリ化しようとしませんでした。コントローラーがJSONを返す場合は、KnockoutJSを調べてください。Knockout JSバージョン2.0は本日リリースされました。JSONに直接プラグインできるため、目に見えるクリックでデータをjavascriptテンプレートに自動的にバインドできます。一方、ajaxアクションメソッドがJSONの代わりにHTMLを返すことを気にしない場合は、LIの子を持つ既に構築されたULを返すことができ、data-myapp-response =を使用して要素に追加できます。 "結果"。成功関数は次のようになります。

success: function(html) {
    var responseId = $(clicked).data('myapp-response');
    if (responseId) {
        $('#' + responseId).empty().html(html);
    }
}

これに対する私の最良の答えを要約すると、アクションメソッドからJSONを返す必要がある場合、サーバー側のビューをスキップするため、これはサーバーMVCではなく、MCにすぎません。htmlでPartialViewResultをajax呼び出しに返す場合、これはサーバーMVCです。そのため、アプリがajax呼び出しに対してJSONデータを返す必要がある場合は、KnockoutJSなどのクライアントMVVMを使用します。

いずれにせよ、レイアウト(htmlタグ)と動作(非同期データロード)が混在するため、投稿したJSは好きではありません。部分的なHTMLビューを持つサーバーMVCまたは純粋なJSONビューモデルデータを持つクライアントMVVMのいずれかを選択すると、この問題は解決しますが、JavaScriptでDOM / HTMLを手動で構築すると、懸念の分離に違反します。

-Javascriptファイルの作成明らかに、縮小機能は.NET 4.5で導入されています。邪魔にならないルートに行く場合、すべてのJS in 1スクリプトファイルの読み込みを妨げるものはないはずです。エンティティタイプごとに異なるJSファイルを作成することに注意すると、JSファイルが爆発的に増加します。スクリプトファイルが読み込まれると、ブラウザは将来のリクエストのためにそれをキャッシュする必要があります。

-複雑なクエリページネーション、ソートなどの機能は複雑であるとは考えていません。私の好みは、これをURLとサーバー側のロジックで処理し、dbクエリを必要に応じて制限することです。ただし、Azureにデプロイされているため、クエリの最適化が重要です。例:/widgets/show-{pageSize}-per-page/page-{pageNumber}/sort-by-{sortColumn}-{sortDirection}/{keyword}。EFおよびLINQ to Entitiesは、.Take()、. Skip()、. OrderBy()、および.OrderByDescending()などのメソッドを使用してページネーションとソートを処理できるため、dbトリップ中に必要なものを取得できます。私はまだclientlibの必要性を発見していないので、正直なところclientlibについてあまり知りません。その他のアドバイスについては、他の回答をご覧ください。

-プロジェクトシルクこれは聞いたことがないので、チェックアウトする必要があります。私はSteve Sanderson、彼の本、彼のBeginCollectionItem HtmlHelper、そして彼のブログの大ファンです。とはいえ、KnockoutJSを運用環境使用した経験はありません。私はそのチュートリアルをチェックアウトしましたが、少なくともバージョン2.0になるまで何かにコミットしないようにしています。前述したように、KnockoutJS 2.0はリリースされたばかりです。

-N層層ごとに異なる物理マシンを意味する場合、いいえ、窓からは何も出ないと思います。通常、3層は3台のマシンがあることを意味します。したがって、プレゼンテーション層としてファットクライアントを使用し、ユーザーのマシンで実行することができます。ファットクライアントは、アプリケーションサーバーで実行され、XMLなどをファットクライアントに返すサービス層にアクセスする場合があります。また、サービス層は、3番目のマシンのSQLサーバーからデータを取得する場合があります。

MVCは1層の1層です。コントローラ、モデル、およびビューはすべて、物理アーキテクチャの1層であるプレゼンテーション層の一部です。MVCはModel-View-Controllerパターンを実装します。これは、追加のレイヤーが表示される場所です。ただし、これら3つの側面を階層またはレイヤーと考えないようにしてください。これら3つすべてをプレゼンテーション層の懸念事項と考えてみてください。

pres / bus / dataコメントの後に更新

さて、あなたはティアとレイヤーを交換可能に使用しています。私は通常、論理/プロジェクト/アセンブリ部門に「レイヤー」という用語を使用し、物理ネットワーク分離にティアを使用します。混乱させて申し訳ありません。

MVCキャンプには、エンティティデータモデルにMVCの「モデル」を使用するべきではなく、ビジネスロジックにコントローラーを使用するべきではないと言う人がかなりいます。理想的には、モデルはビュー固有のViewModelである必要があります。Automapperのようなものを使用して、ドメインモデルからエンティティを取得し、ビューで使用するために特別に作成されたViewModelにDTOします。

すべてのビジネスルールもドメインの一部である必要があり、MVCプレゼンテーションレイヤーではなく、ドメインレイヤーで適切なものを使用して、ドメインサービス/ファクトリパターンを使用して実装できます。コントローラーは、モデルほど馬鹿げているわけではありませんが、馬鹿げている必要があり、ビジネス知識を必要とするものについてはドメインに責任を与える必要があります。コントローラはHTTPリクエストとレスポンスのフローを管理しますが、実際のビジネス上の価値があるものはすべてコントローラの給与等級を超えている必要があります。

そのため、プレゼンテーションレイヤーとしてMVCを使用したレイヤーアーキテクチャを引き続き使用できます。設計方法に応じて、アプリケーション層、サービス層、またはドメイン層のクライアントです。ただし、最終的にはエンティティモデルはMVCのモデルではなく、ドメインの一部である必要があります。


私はこの答えに完全に同意します!特に:•ResharperはMVCの天才です...エラーチェックからIDEナビゲーションまで、その有用性には驚かされます!• サーバー側のMVCは、ほとんどの場合最良のアプローチです。•MVCは3つの独立した層ではなく、単一のプレゼンテーションレイヤーです。
スコットリッピー

非常に良い答え、間違いなく私が私の担当者の費用で探していたもの。あなたがトロント地域にいる場合、飲み物は私にあります:)

ところで、物理的にどこに座っていても、常にN層をPres / Bus / Dataと見なしていました。MVCは基本的に3を組み合わせているため、MVCがそのアーキテクチャをほとんど削除すると言った理由です。

ViewModel、ビューごとのモデル、アプローチに対して警告します。最近、DTOからViewModelへのこの抽象化を持たないことを望んでいた状況に遭遇しました。参照:stackoverflow.com/q/7181980/109456

一般的なルールとして、jQueryを見るのは好きではなく、サーバーサイドの開発者がJQまたはDOM APIが内部でビジネスを行うことで、すぐに理解できるインターフェースを持つオブジェクトを作成します。また、DjangoのURLConfigコンセプトが大好きで、ページに実装するためのオブジェクトのセットアップに役立つことがわかりました。MVが何なのかわかりませんか?ライブラリは私のために行うことになっています。それらは問題に完全に適合しているわけではありません。IMOとDOM +イベントの委任は、特定の構造に過度に縛られることなくページを処理するために必要なすべてのモデルです。
エリックReppen

6

完全な答えを書くつもりはありませんが、いくつかのヒントを共有したいと思います。

私のヒント:

1.プロジェクトの構造
デフォルトのMVC構造は私には向いていないことがわかりました。私は通常、同じエンティティ(製品、注文、顧客など)のコントローラー、ビュー、およびモデルで同時に働いています。そのため、同じフォルダにファイルを入れたいのですが、名前空間は異なります。

2.データ
Linq-to-SQLまたはEFを使用する場合、後悔します。
PetaPocoを使用します。これにより、マッピングの苦痛なしに、レコードを取得および更新するSQLを実行できますが、新しい方法を学んだり、パフォーマンスの悪夢を見たりすることはありません。

PetaPoco属性を使用して初期POCOクラスを作成し、フィールドが追加または削除されるとクラスを変更するコードジェネレーターがあります。

PetaPocoは動的クラスと標準クラスで動作するため、妥協する必要はありません(Massiveはすべて動的クラスであり、Dapperはすべて標準クラスです)

また、ビルトインSqlBuilderを使用して、エンティティのすべての標準結合を含むマスター SQLを生成しますが、WHEREを含まないため、1つのエンティティまたはリストを取得するために同じSQLを再利用します。

3. JQuery 一般的なjQuery呼び出し(HTML要素内にデータを詰め込む)を使用して、UIの一部を標準化できます。

たとえば、私はこれを削除するために持っています。

var deleteLinkObj;
// delete Link
$('.jbtn-borrar').click(function () {
    deleteLinkObj = $(this);  //for future use
    $('#delete-dialog').dialog('open');
    return false; // prevents the default behaviour
});
$('#delete-dialog').dialog({
    autoOpen: false, width: 400, resizable: false, modal: true, //Dialog options
    buttons: {
        "Borrar": function () {
            $.post(deleteLinkObj[0].href, function (data) {  //Post to action
                if (data == 'OK') {
                    deleteLinkObj.closest("tr").hide('fast'); //Hide Row
                }
                else {
                    alert(data);
                }
            });
            $(this).dialog("close");
        },
        "Cancelar": function () {
            $(this).dialog("close");
        }
    }
});

クラスjbtn-borrarをハイパーリンクに追加するだけで、ダイアログが表示され、レコードが削除され、非表示になりますtr

しかし、それを考えすぎないでください。あなたのアプリはあらゆるビューで小さなタッチで輝きます。

クライアントMVCとサーバーMVC
サーバーMVC。初期レンダリングで使用できる部分ビューを利用し、同じビューを使用してAjaxで一部のパーツを更新します。この素晴らしい記事をご覧ください

複雑なクエリを処理する方法(レポートと呼びます)
プロパティとしてレポートパラメーターを持つクラス(MVC自動マッピングを使用するのに便利)とGenerate、クエリを実行してカスタムクラスのリストを埋めるメソッド(使用する場合) 'ViewModelに適合するクラスはあり
ません)このクラスをビューのモデルとして使用し、生成されたリストをテーブルに入力できます。

MicrosoftのProject Silk
Overarchitected。逆方向にできるだけ速く実行します。


面白いことに、Project Silkを読んでいると、このしつこい感じがし続け、配置できませんでした。Overarchitectedは...ということであったかもしれない

3

1.プロジェクトの構造

ソリューションに2つのプロジェクトファイルがあります

1)サービス/ビジネス層すべてのビジネスロジックとDBアクセスコードおよびPOCOをこの別のプロジェクトに配置します。ORMを使用して既にDBレイヤーを抽象化している場合、データアクセスレイヤーは不要です。

2)UIレイヤーには、すべてのビュー、コントローラー、モデル、スクリプト、CSSが含まれます

コントローラー、ビュー、スクリプト、CSSがすべて同様のフォルダー構造を使用するようにします。また、可能な限りURLパスに一致するようにファイルを構成します。カスタムルーティングを記述する必要がないようにします。

DisplayTemplates、EditorTemplates、Partialビュー、およびSharedフォルダーを可能な限り使用します。

次に、すべてのスクリプトを同じ領域、c#ファイルのコントローラーに一致するように構成します。したがって、ルートにcommon.jsファイルがあり、ページごとにjsファイルがあり、各領域にcommon.jsファイルがあります。

通常2 + nのCSSファイル(nは領域の数)1番目のCSSファイルは、ページの読み込み時間を短縮するためのランディングページ専用のCSSです(おそらく、ビジネス/企業環境ではそれほど重要ではありません)2番目のCSSファイル他のすべてのページのすべてのスタイルを含むcommon.cssです。次に、各エリアの別のcommon.cssファイル、たとえば、すべての管理ページのCSSを持つAdminArea.cssファイル。

2.データアクセス

Entity Frameworkを使用する場合、POCOSで非常にうまく機能し、保守するモデルがないため、CodeFirstを使用します。nHibernateははるかに強力ですが、ステッパー学習曲線を備えています。DB結果のページングには、すべてのビューに使用する再利用可能なutil c#クラスとpatialビューがあります。

複雑なクエリとレポートの生成には、ストアドプロシージャを使用します。LINQの記述と保守がはるかに簡単で、より強力な機能を提供します。SSRSなどの他のサービスでも再利用できます。オートマッパーを使用して、返されたデータセットを、フレームワークが使用するPOCOと同じPOCOに変換します。

3.クライアント側のコード編成とUIレンダリング

Eduardo Molteniの回答には良いコード例があります。さらに、優れたテンプレートとバインディングの両方があるため、knockoutjsの使用をお勧めします。私が多く使用するすべてのAJAX呼び出しにJSONを使用する場合、UIオブジェクトをJSオブジェクトに自動マップすることで時間を大幅に節約できます。

一般的な質問

複雑なクエリはストアドプロシージャに存在する必要があります。(emeraldcode.comのコメントを参照)

このMVCを使用してN層アーキテクチャを維持します。


1

リストに挙げた3つのテクノロジーを使用する予定がある場合は、まずOrchard CMSの採用を想定することから始めるべきだと信じるようになりました。私はそれがあなたの中心的な要件に対する最良の単一の答えだと信じています:

スケーラビリティと、リッチで高速でクリーンなUIを作成する能力を維持しながら、コードとロジックを整理するための最適な戦略は何ですか?

Ochardシナリオでは、構成メカニズムを通じて対処できないものは、無料のオンラインモジュールを追加するか、独自のモジュール(もちろんC#、カミソリなど)を作成することで対処できます。コード編成はオーチャードの強みです。

データアクセスに関しては、フルボアORMには十分な長所と短所があり、マイクロORMがベストテイクであると考えるようになりました。MassiveまたはDapperを試してください。両方ともHanselminutesで紹介されました。このことを言って、この2つを要約します。プロジェクトの規模が大きくなると、SQLからの抽象化はほとんど常に壊れます。最終的に、DBアクセスの最適なソリューションは、SQLと呼ばれるこの抽象化です(少し皮肉ですが、本当です)。micro-ORMをそれで動作させると、金が手に入ります。

オーチャードをマイクロORMと一緒に入れると、スチールをバターのようにスライスできます。Er、つまり、ハンドオフを受け取るチームが迅速に開発、スケーリング、および容易に保守可能なコードを作成できることを意味します。


0

この質問を見逃した方法はわかりませんが、2年後に2セントを追加します。

クライアントMVCとサーバーMVCの違い 私のプロジェクトはすでにサーバー側のMVC構造になっているので、Backbone.jsが提供するようなクライアントMVCがまだ必要ですか?

MVCとMV?クライアント側にプッシュされる前でさえ、基本的にマーケティング用語に発展しました。マーケティング用語は、データが何らかの形で他のものから分離されることを本当に約束するだけです。どのアプローチをとろうとも、プレゼンテーションやインタラクションの可能性に影響を与えるHTMLを変更する直前または途中で、ビジネスがデータで何をしたいかを整理するのに絶対に最も恐ろしい場所です。

「ビューロジック」について特別なことはありません。同じ原則がすべてのロジックに適用されるはずです。そして、それは、今までにやった方がずっと意味のあることは何もしないでください。データを渡すか新しいプロセスを開始する前にすべてのアヒルが並んでいる場合、システム内の他の何かが同様のことを行うために、その前のフェーズがはるかに再利用可能になる可能性があります。

各オブジェクト(OrderHeader.jsなど)に対してJavascriptファイルを作成し、ビルド中に縮小/マージする必要がありますか?または、OrderHeader、OrderDetails、Reportsなどのロジックを持つOrder.jsだけが必要ですか?

それは本当にあなた次第ですが、私は1つのファイル、1つのクラスのものから逃げようとします。たとえば、抽象ファイルとインターフェイス、実装するファイルなどを見つける必要がある理由がわかりません。より広範な懸念に分類します。ctrl + fは、少し長くなってもそれほど難しくありません。

ただし、JSを再結合してWeb上のファイルを小さくすることは決してしないでください。ブラウザはJSをキャッシュするため、古いJSを新しいファイルに固定することにより、同じJavaScriptのリロードを強制するだけです。膨大な量のJavaScriptがなければ、ページにすべてのJSを置くべきではないのは、特定の場所で重複/グレー領域のないサイトの特定のセクションに非常に固有の大量のJSが不要になる場合だけですページ。

また、FFSは、Web上のJavaScriptを使用した依存関係管理に大騒ぎしません。中程度から複雑度の低いWebサイトのRequire.jsでは、赤ちゃんアザラシをクラブにしたいと思います。サードパーティのライブラリを一番上のブロックに貼り付けます。2番目のブロックの社内ライブラリ。そして、その3番目のブロック内の実装コード(社内ライブラリコードの10分の1になることはありません-つまり、非常に簡潔で明確で理解しやすい)。

複雑なクエリはどのように処理する必要がありますか?現在、私の主要な理論は/ Reports / Orders-By-Date /またはそれらの線に沿ったものであり、カスタムデータセット(またはViewModel)をRazorビューにレンダリングするカスタムSQLクエリを使用しています。しかし、ページング、ソートなどはどうですか?これはクライアント側またはサーバー側で行う方が良いですか?(より大きなデータセット-2〜3秒のSQLクエリを想定)MicrosoftのProject Silkを読みました。これは良い方法ですか?Backbone.jsまたは他の製品と比較してどうですか?

正直なところ、顧客にとって悪臭のない、あなたにとってより簡単なものは何でも言うでしょう。Webページは、最新のテクノロジーでは非常に高速にロードされます。Ajaxでの実装があなたにとって大きな苦痛であるならば、そうしないでください。あなたが最もよく知っていることを行えば、後で空想を得て、ページングでそれがどのように好きかを見ることができます。新しい複雑なアプリをゼロから作成している場合は、基本的なものから始めて、後からきちんと入力してください。

私はN層アーキテクチャに非常に慣れていますが、これらの概念はそれを窓からいくらか投げ出しますか?MVCは、以前はフロントエンドまたはトップティアであったミニNティアセクションの束のようです。

誰がどのMVを空想しているかに本当に依存していますか?です。IMO、小宇宙は非常にうまく機能する傾向があります。データ、通信、およびビュー関連のものを内部で分離するウィジェットのクラスは、非常に効果的です。クライアント側のWebで重要なのはIMOであり、再構築によって物事を理解、再利用、および修正することが困難な小さな小さな懸念に不必要に断片化することなく、懸念を分離するバランスを維持することです。ここでは、基本的な "duh" OOPがうまく機能しています。複雑なプロセスは必要ありません。移動して、何かをするように指示できる、明らかに名前の付いたものが必要です。その面でいくつかのヒントがあります:

  • KISS(OOP)インターフェイス DOMやjQuery、またはピンチヒットのサーバー側開発者が実装コードでかなり迅速に理解できなかったものを見たくない。その人が知っておく必要があるのは、divコンテナをスラップするクラスと、特定のページでかなり一般的なUIのセットをアクティブにするために切り替えるスイッチです。テーマのバリエーションは、document.get <anything>を確認したり、CSSの最も基本的なものを超えて理解したりする前に、十分に文書化/コメント化されたオプションオブジェクトを渡すことで実現できます。

  • さて、どうやってそれをしますか?さて、すでにモデルがあります。DOMと呼ばれます。そして、イベントの委任があります。イベントのバブリングを無差別にシャットダウンしていない場合(それはしないでください-有用なのでそこにあります)、必要に応じて体からでもすべてを拾うことができます。次に、渡されたイベントオブジェクトのターゲットプロパティを調べて、「何でも」だけを判断します。HTMLドキュメントを賢明構造化する場合、委任モデルとして使用しない理由はありません。動作とコンテンツ構造は自然にリンクされています。2つが重複する識別子を持つことは問題ありません。

  • データバインディングにお金をかけないでください。「支払う」とは、もちろん、「コードベースにライブラリを平手打ちして、あなたが物事を行うだけだと主張することを意味します。JQのイベントシステムにより、非常に簡単になります。

例の時間:

function PoliticianData(){ //a constructor

    var
        that = this, //I hate 'that' but example so convention

        flavorsOfLie = {

            lies: "Oh Prism? Psh... no we're all good. There's a guy keeping an eye on that.",

            damnedLies: "50% of the people chose to not give a damn when asked whether it was better to let the terrorists win or not give a damn."

        }
    ;//end instance vars

    this.updateLies = function( lieType, newData ){
        flavorsOfLie[lieType] = newData;
        $(that).trigger({type:'update', lieType:lieType, newData: newData });
    }

    //so everytime you use the updateLies method, we can have a listener respond
    //and pass the data
}

var filthyLies = new PoliticianData();

$(filthyLies).on('update', function(e){
    stickNewDataInHTMLWithSomeFuncDefinedElsewhere(e.lieType, e.newData);
} );

filthyLies.update('damnedLies','50% of the people said they didn\'t give a damn');
//oh look, WaPo's front page just changed!
  • ウェブを隠さないでくださいを隠さクライアント側をサーバー側やアプリケーション開発者にとって簡単にするための初期の試みのすべてにおいて、この重大なポイントに依存した吸盤の主な原因。HTTPリクエストは複雑ではありません。理解しやすくするために、各ステージで18の!@#$ ingレイヤーの紛らわしいイベント名の怪物を必要としませんでした。同様に、クライアント側について多くのことを知る必要がありますが、その上に大きな巨大なモデルを平手打ちすることでHTMLと対話するDOMから隠す理由はありません。それはすでに大きな巨大なモデルであり、非常にうまく機能します。それをもう少し管理しやすくするために必要なのは、賢明なOOPプラクティスと、JSとDOMの知識です。

  • 柔軟性を優先

EXTjs <====柔軟性スケール====> jQuery(必ずしもそのプラグインのいずれかではない)

IMO、DIYを迅速に実行できるツールは、常により良い選択です。あなたのためにそれをすべて行ったツールは、あなたの頭の上の誰も特に細部にこだわりがなく、あなたがあなたを助けることになっているまさにそのものにコントロールを譲ることを気にしないときのみ正しい選択です。実際に、HTMLを検証して、まったく同じ表示特性を持つ別の種類の要素を忍び込まないようにするプラグインを見てきました。どうして?私には理論しかありません。結局のところ、意図していない方法で誰かが自分のものを使用するという考えを本当に嫌っている補完者に帰着すると思います。それは常に誰かがあなたにUIでやりたいことです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.