我正在开发一个新的ASP .NET网站,它实际上是我们刚刚发布的另一个网站中的页面的一个子集。两个或三个页面需要进行小的调整,但没有什么重要的。
显而易见的答案是简单地将所有代码和标记文件复制到新项目中,进行上述调整,并考虑完成工作。但是,由于它将创建大量重复的代码,我根本不热衷于此。
我的下一个想法是将页面代码(即代码隐藏文件)移动到一个单独的程序集中,然后可以从两个站点引用它们。这有点尴尬但是如果你不带它的设计器文件,你会得到很多与缺少控件有关的构建错误。我不认为移动设计器文件是一个好主意,因为每次更改标记时都需要重新生成。
有没有人对这个问题的清洁解决方案有任何建议?
答案 0 :(得分:2)
您可能想看一下MVP模式。由于您可能正在使用WebForms,因此很难迁移到ASP.Net MVC,但您可以很容易地将MVP实现到现有应用程序中。
在基本级别上,您可以将所有业务逻辑移动到Presenter类中,该类具有代表某种接口的View:
public class SomePresenter
{
public ISomeView View{get; set;}
public void InitializeView()
{
//Setup all the stuff on the view the first time
View.Name = //Load from database
View.Orders = //Load from database
}
public void LoadView()
{
//Handle all the stuff that happens each time the view loads
}
public Int32 AddOrder(Order newOrder)
{
//Code to update orders and then update the view
}
}
您可以定义接口以保存要显示的原子类型:
public interface ISomeView
{
String Name {get; set;}
IList<Order> Orders{get; set;}
}
一旦定义了这些,您现在可以简单地在表单中实现界面:
public partial class SomeConcreteView : System.Web.UI.Page, ISomeView
{
public SomePresenter Presenter{get; set;}
public SomeConcreteView()
{
Presenter = new SomePresenter();
//Use the current page as the view instance
Presenter.View = this;
}
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
Presenter.InitializeView();
}
Presenter.LoadView();
}
//Implement your members to bind to actual UI elements
public String Name
{
get{ return lblName.Text; }
set{ lblName.Text = value; }
}
public IList<Order> Orders
{
get{ return (IList<Order>)ordersGrid.DataSource; }
set
{
ordersGrid.DataSource = value;
ordersGrid.DataBind();
}
}
//Respond to UI events and forward them to the presenter
protected virtual void addOrderButton_OnClick(object sender, EventArgs e)
{
Order newOrder = //Get order from UI
Presenter.AddOrder(newOrder);
}
}
正如您所看到的,您的代码现在非常简单,因此代码重复并不是什么大问题。由于核心业务逻辑全部包含在某个DLL中,因此您不必担心功能不同步。演示者可以在多个视图中使用,因此您可以高度重用,只要您遵守合同,就可以自由地更改UI而不会影响业务逻辑。
同样的模式也可以应用于用户控件,因此您可以根据需要进行模块化。这种模式还可以让您无需运行浏览器就可以对逻辑进行单元测试:)
patterns and practices群有一个很好的实现:WCSF
但是,您不必使用其框架来实现此模式。我知道这一开始看起来有点令人生畏,但它会解决你遇到的许多问题(在我看来)。
答案 1 :(得分:1)
创建用户控件(小部件)或模板以调整您想要实现的目标。
也可以使用CSS样式或JavaScript实现相同的效果。
答案 2 :(得分:0)
为什么不从您要共享的页面创建用户控件(或自定义控件)?然后,您可以在两个站点中重复使用它们。
答案 3 :(得分:0)
我们在项目中使用的是什么(JSP,而不是ASP,但在构建文件时肯定不是问题?)是拥有公共文件的基本文件夹,然后是另一个(“实例”)其他文件和覆盖的文件夹,我们的构建脚本(在ANT中,Maven也应该没问题)将首先复制基本文件夹,然后根据提供的参数选择要复制的实例文件。
因此,我们可以更改基础中的文件,并将其应用于所有实例。
问题是更改基本文件不会更新任何覆盖它的实例文件,但至少可以为这些更新创建进程。大概你也可以使用SVN(etc)修订来标记构建错误,实例文件比基本文件旧,但是我们还没有实现任何聪明的东西。
此外,您的后端代码(在我们的示例中为Struts操作)将最终处理所有情况,而不是仅处理任何特定实例的情况。但至少所有代码都在一个地方,逻辑应该是明确的(“if(instance == FooInstance){doFooInstanceStuff(...);}”)。