从一个网站重用另一个网站的最佳方法是什么?

时间:2008-11-26 14:10:33

标签: asp.net

我正在开发一个新的ASP .NET网站,它实际上是我们刚刚发布的另一个网站中的页面的一个子集。两个或三个页面需要进行小的调整,但没有什么重要的。

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

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

有没有人对这个问题的清洁解决方案有任何建议?

4 个答案:

答案 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(...);}”)。