SOLID原则和网页类(SOLID principles and web page class)

2019-09-20 08:14发布

我试图写新的类和代码时遵循SOLID原则。

我的问题是关于延长Page类即ASPX文件ASP.NET类。 如果我有有一个创建Page_Load事件的网页类中的多个对象的实例,例如Person类,体育类等那么我相信这个页面类是紧密耦合与这些类。 这样的话还是我失去了一些东西明显? 难道说所有类应揭露接口和客户端(aspx页面)应该使用接口,而不是直接实例化的类。

我发现接口有用的,如果多态性涉及例如使用学生界面在运行时创建的研究生或本科生的一个实例。 如果所有的类都具有的接口?

Answer 1:

如果您创建内您的实体Page类(表示层),你显然违反了单一职责原则,因为页面类将有多种原因改变。

相反,移动这个逻辑,业务层和创建处理这个逻辑的服务。

您的网页需要交谈的服务接口,而不是实现(DIP)和该服务接口需要为很窄(ISP); 可能只是有一个方法。

如果您打包服务的所有参数到一个单一的对象,从而分离数据和行为,并使用通用接口为您服务(即ICommandHandler<TCommand>你甚至可以遵守的OCP,因为你现在可以添加行为(如验证,交易,死锁检测,异步处理,排队)到服务,任何内部消除更改应用程序。

最后要注意,不要创建实体的接口。 这是相当无用的,并掩盖了你的代码。



Answer 2:

我不会在代码中实例化对象的后面。 我要做的就是调用实例获取对象的服务 - 它实例它们与数据库中的数据。 我在一个母版也做了服务公众和引用它是这样的:

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

当然,你应该检查,以确保(Page.Master为MasterBase)不为空....


编辑按要求

我创建了一个基础母版页的所有其他网站母版页必须从继承。 在此基础母版页的构造我所有实例所必需的服务。 当然,如果通了现场不使用的服务,他们可以是不同的,更合适的部分,一般法师页面上实例化。

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页面上的服务,并从具体项目的角度来看,这是可以接受的,使所有母版页从这个基地页继承。



Answer 3:

你可以做到这一点的方法之一是配置在Global.asax你的依赖

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

当你需要符合URL模式和文件路径适合您的网站。 这会给你的句柄服务对象,通过服务路线值

然后,您可以声明一个基类页

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响应文件



文章来源: SOLID principles and web page class