2008-11-26 71 views
3

我正在开发一个新的ASP .NET网站,它实际上是我们刚刚发布的另一个网站中的网页的子集。两三页将需要较小的调整,但没有意义。在另一个网站中重用页面的最佳方式是什么?

显而易见的答案是将所有代码和标记文件复制到新项目中,进行上述调整,并考虑完成工作。但是,由于其创建的重复代码的数量,我并不热衷于此。

我的下一个想法是将页面代码(即代码隐藏文件)移动到一个单独的程序集中,然后可以从这两个站点中引用它们。这有点尴尬,但是如果你不带设计器文件,你会得到很多与缺失控件有关的构建错误。我不认为移动设计器文件是一个好主意,因为每当标记被修改时都需要重新生成。

有没有人有任何建议干净的解决这个问题?

回答

2

您可能想看看MVP模式。由于您可能正在使用WebForms,因此很难迁移到ASP.Net MVC,但您可以很容易地将MVP实现到现有的应用程序中。

在基本层面上,你会移动所有的业务逻辑到有一种观点认为代表了某种界面的演示类:

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

不过,你不必使用他们的框架来实施这种模式。我知道这可能起初看起来有点令人生畏,但它会解决许多你遇到的问题(在我看来)。

0

为什么不从您想要共享的页面创建用户控件(或自定义控件)?然后,您可以在这两个网站上重复使用这些内容。

1

创建用户控件(小部件)或模板来调整你想要实现的。

也可以用CSS样式或JavaScript来实现。

0

我们在我们的项目中使用的是什么(JSP,不是ASP,但是当涉及到构建和文件时它肯定不是问题?)是有一个公用文件的基础文件夹,然后是另一个(“实例” )文件夹和覆盖文件,我们的构建脚本(在ANT中,Maven应该也可以)会先复制基础文件夹,然后根据提供的参数选择要复制的实例文件。

因此,我们可以更改基础中的文件,并将其应用于所有实例。

一个问题是,更改基本文件不会更新覆盖它的任何实例文件,但至少可以为这些更新创建一个进程。据推测,你也可以使用SVN(等)修订标志一个构建错误是一个实例文件比基本文件旧,但我们还没有实现任何聪明的东西。

此外,您的后端代码(我们的案例中的Struts操作)将最终处理所有案例,而不是仅处理任何特定实例的案例。但至少所有的代码都在一个地方,逻辑应该清楚(“if(instance == FooInstance){doFooInstanceStuff(...);}”)。

相关问题