首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SOLID principles和网页类

SOLID principles和网页类
EN

Stack Overflow用户
提问于 2012-07-27 22:33:19
回答 3查看 358关注 0票数 2

在编写新的类和代码时,我正在尝试遵循可靠的原则。

我的问题是关于扩展Page类的ASP.NET类,即ASPX文件。如果我有一个页面类,它有一个page_load事件来创建多个对象的实例,例如Person类、Sport类等,那么我相信这个页面类与这些类是紧密耦合的。是这样,还是我漏掉了什么明显的东西?难道所有的类都应该公开接口,而客户端(aspx页面)应该使用接口而不是直接实例化类吗?

如果涉及到多态,我发现接口很有用,例如,在运行时使用Student接口来创建graduate或useful的实例。所有的类都应该有接口吗?

EN

回答 3

Stack Overflow用户

发布于 2012-07-28 02:38:26

如果您在Page类(表示层)内创建实体,则显然违反了单一责任原则,因为页面类将有多个更改原因。

相反,应将此逻辑移动到业务层,并创建一个处理此逻辑的服务。

您的页面将需要与服务接口对话,而不是与实现(DIP)对话,并且此服务接口需要很窄(ISP);可能只有一种方法。

如果您将服务的所有参数打包到单个对象中,从而分离数据和行为,并为您的服务使用通用接口(即ICommandHandler<TCommand>),您甚至可以遵守OCP,因为您现在可以向服务添加行为(如验证、事务、死锁检测、异步处理、队列),而无需对应用程序进行任何更改。

最后注意,不要为实体创建接口。这是相当无用的,并且使你的代码变得模糊。

票数 1
EN

Stack Overflow用户

发布于 2012-07-27 23:17:23

我不会在后面的代码中实例化对象。我所做的是调用一个服务来实例化gets对象-它用数据库中的数据实例化它们。我还在母版页中公开了该服务,并像这样引用它:

代码语言:javascript
复制
IUser _user = (Page.Master as MasterBase).RegistrationService.GetPersonFromEmailAddress(txtUser.text);

当然,您应该检查以确保(Page.Master as MasterBase)不是null...

按请求编辑

我创建了一个所有其他网站母版页都必须继承的基母版页。在这个基母版页的构造函数中,我实例化了所有必需的服务。当然,如果没有在整个站点中使用这些服务,则可以在不同的、更合适的通用部分母版页上实例化这些服务。

代码语言:javascript
复制
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);
}

如上所述,网站上使用的任何母版页都将从基类继承:

代码语言:javascript
复制
public partial class MasterContent : MasterBase

任何引用母版页的UI页面(在我的例子中几乎都引用了它们)

代码语言:javascript
复制
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="activities.aspx.cs" Inherits="activities" MasterPageFile="~/MasterContent.Master" %>

现在可以访问后台代码中的不同服务:

代码语言:javascript
复制
IUser _user = (Page.Master as MasterBase).RegistrationService.GetPersonFromEmailAddress(txtUser.text);

正如在下面的评论中提到的,不同的UI页面确实与基母版页有紧密的耦合,但我不知道在一般的ASP.NET web窗体应用程序中有什么更好的方法来做到这一点。它减少了在每个UI页面上实例化服务的需要,并且从特定于项目的角度来看,使所有母版页都继承自该基页是可以接受的。

票数 0
EN

Stack Overflow用户

发布于 2012-07-30 20:59:36

一种方法是在Global.asax中配置依赖项

代码语言:javascript
复制
public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("",
        "Create/{Service}",
        "~/categoriespage.aspx",{"Service", new WhatEverSErvice()} );
}

你需要适应URL模式和文件路径,以适合你的网站。这将通过服务路由值为您提供服务对象的句柄

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

代码语言:javascript
复制
public abstract class BasePage<TService> : Page where TService : IService {

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

在这里,IService是一个你必须定义的接口,它是你的服务的基础(如果这样的接口有意义,否则只需省略where子句)

然后让所有的页面都派生自这个类,当您需要特定的服务时,只需编写如下代码

代码语言:javascript
复制
var myFoo = Service.CreateFoo();

当用户在/后面提供一个字符串时,这种方法在错误场景中的行为确实有些奇怪。您可以通过扩展该属性来处理此问题,因为它基本上是一个未找到的文件(提供的URL无效),因此您可以返回404 FNF响应

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11689959

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档