2

新しいクラスとコードを作成するときは、SOLIDの原則に従おうとしています。

私の質問は、Pageクラスを拡張するASP.NETクラス、つまりASPXファイルについてです。複数のオブジェクトのインスタンスを作成するpage_loadイベントを持つページクラス(Personクラス、Sportクラスなど)がある場合、このページクラスはこれらのクラスと緊密に結合されていると思います。これは事実ですか、それとも私は何か明らかなことを見逃していますか?すべてのクラスがインターフェイスを公開し、クライアント(aspxページ)がクラスを直接インスタンス化するのではなく、インターフェイスを使用する必要がある可能性があります。

ポリモーフィズムが関係している場合、たとえば学生インターフェースを使用して実行時に卒業生または学部生のインスタンスを作成する場合、インターフェースが役立つと思います。すべてのクラスにインターフェースが必要ですか?

4

3 に答える 3

1

クラス (プレゼンテーション レイヤー)内にエンティティを作成する場合Page、ページ クラスには複数の変更理由があるため、明らかに単一責任の原則に違反しています。

代わりに、このロジックをビジネス レイヤーに移動し、このロジックを処理するサービスを作成します。

ページは、実装 (DIP) ではなく、サービス インターフェイスと通信する必要があり、このサービス インターフェイスは狭い (ISP) 必要があります。おそらく1つの方法しかありません。

サービスのすべての引数を 1 つのオブジェクトにパッケージ化してデータと動作を分離し、サービスの汎用インターフェイス (つまりICommandHandler<TCommand>) を使用すると、OCP に準拠することもできます。アプリケーションに変更を加えることなく、トランザクション、デッドロック検出、非同期処理、キューイング) をサービスに追加します。

最後に、エンティティのインターフェイスを作成しないでください。これはかなり役に立たず、コードがわかりにくくなります。

于 2012-07-27T18:38:26.017 に答える
0

これを行う 1 つの方法は、Global.asax で依存関係を構成することでした。

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("",
        "Create/{Service}",
        "~/categoriespage.aspx",{"Service", new WhatEverSErvice()} );
}

サイトに合わせて URL パターンとファイル パスを合わせる必要がある場所。これにより、Service ルート値を介してサービス オブジェクトへのハンドルが提供されます。

次に、基本ページ クラスを宣言できます。

public abstract class BasePage<TService> : Page where TService : IService {

   protected TService Service{
       get {
           return Page.RouteData.Values["Service"] as TService;
       }
   }
}

これは、サービスの基礎となるインターフェイスを定義する必要がありますIService(そのようなインターフェイスが理にかなっている場合は、単に where 句を省略してください)。

次に、すべてのページをこのクラスから派生させ、特定のサービスが必要なときはいつでも次のように記述します。

var myFoo = Service.CreateFoo();

このアプローチは、ユーザーが / の後に文字列を指定すると、エラー シナリオでやや奇妙な動作をします。これは基本的にファイルが見つからない (指定された URL が無効である) ため、プロパティを拡張することでこれを処理できます。404 FNF 応答を返すことができます。

于 2012-07-30T12:59:35.777 に答える
0

コード ビハインドでオブジェクトをインスタンス化することはありません。私がしているのは、オブジェクトをインスタンス化するサービスを呼び出すことです。これは、オブジェクトをデータベースからのデータでインスタンス化します。また、マスターページでサービスを公開し、次のように参照します。

IUser _user = (Page.Master as MasterBase).RegistrationService.GetPersonFromEmailAddress(txtUser.text);

もちろん、(Page.Master as MasterBase)がnullでないことを確認する必要があります....


リクエストによる編集

他のすべてのサイト マスター ページが継承する必要があるベース マスター ページを作成します。この基本マスター ページのコンストラクターで、必要なすべてのサービスをインスタンス化します。もちろん、サービスがサイト全体で使用されていない場合は、別の、より適切なセクション全般のマスター ページでインスタンス化できます。

public readonly IRegistration RegistrationService;
public readonly IEventService EventService;
public readonly IEmailSendingService EmailService;
private readonly IMenuService _menuService;

public MasterBase()
{
    RegistrationService = new BusinessLogic.Registration(DatabaseConnectionString);
    EventService = new EventService(DatabaseConnectionString);

    var fromAddress = ConfigurationManager.AppSettings["Webmaster"];
    var defaultToEmailAddress = ConfigurationManager.AppSettings["toEmail"];
    EmailService = new EmailSendingService(BaseUrl, fromAddress, defaultEmailAddress);
    _menuService = new MenuService(DatabaseConnectionString);
}

前述のように、サイトで使用されるすべてのマスター ページは、ベースから継承されます。

public partial class MasterContent : MasterBase

マスター ページを参照する任意の UI ページ (私の場合はほぼすべて)

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="activities.aspx.cs" Inherits="activities" MasterPageFile="~/MasterContent.Master" %>

コード ビハインドでさまざまなサービスにアクセスできるようになりました。

IUser _user = (Page.Master as MasterBase).RegistrationService.GetPersonFromEmailAddress(txtUser.text);

以下のコメントで述べたように、さまざまな UI ページはベース マスター ページと密結合していますが、一般的な ASP.NET Web フォーム アプリケーションでこれを行うより良い方法を知りません。これにより、すべての UI ページでサービスをインスタンス化する必要性が軽減され、プロジェクト固有の観点から、すべてのマスター ページをこのベース ページから継承することが許容されます。

于 2012-07-27T15:17:23.467 に答える