当前位置: 代码迷 >> 综合 >> 基于Castle+IBatisNet+Castle.MVC的ASP.NET构架
  详细解决方案

基于Castle+IBatisNet+Castle.MVC的ASP.NET构架

热度:32   发布时间:2023-12-06 04:05:26.0

    本文描述Castle+iBatisNet+Castle.MVC的ASP.NET架构及其搭建方法。之前也尝试过Castle+iBatisNet+MonoRail的架构,该架构非常类似于J2EE中的Spring + Struts + iBatis的轻量级架构。虽然我们已经非常熟悉这种架构模式,但是放在ASP.NET环境中,他不能充分利用ASP.NET的优势,我们更清晰与一种既有MVC架构,同时能充分发挥ASP.NET优点的架构,查阅大量资料之后,最终选择了Castle + iBastisNet + Castle.MVC架构,虽然Castle.MVC目前还不成熟(不过有源码),我们还是选择了他。鉴于目前这方面的资料非常少,本文将我们在这方面的经验积累下来,一方面供自己日后查阅,一方面也供研究此架构的朋友参考。本文重点突出可操作性,理论上的讨论不做说明。

1.环境

  • Visual Studio.Net 2005
  • Castle http://www.castleproject.org/
  • IBatisNet http://ibatis.apache.org/
  • Castle.MVC 从Castle的svn版本库中下载(目前并未正式发布)
  • 辅助环境:nant、nunit

 

2.构架搭建Castle+IBatisNet+Castle.MVC

    由于Castle与IBatisNet的关系比较微妙,我们先下载源码。编译的时候采用一点小技巧,下面先下载代码。

 

2.1下载IBatisNet与Castle

  • IBatisNet的下载地址是http://ibatis.apache.org/dotnetdownloads.cgi ,我们下载IBatisNet.DataMapper1.5,解压到本地硬盘。
  • 由于Castle.MVC目前还未正式发布,要下载Castle.MVC,我们要从Castle的版本库里面下载,我们现在最新的Release版下载,下载地址
    https://svn.castleproject.org/svn/castle/tags/Release-Jan-06

 

2.2 编译IBatisNet与Castle

      Castle提供了与IBatisNet的集成。但是从版本库中下载来的Castle集成的时IBatisNet.DataMapper 1.3版本,而我们下载的IBatisNet.DataMapper是1.5版的,我们希望用Castle集成新的1.5版的IBatisNet.DataMapper。
      由于IBatisNet与Castle的特殊关系,具体编译的时候需要一点小的技巧。IBatisNet中大量使用了Castle,虽然下载的IBastisNet包中包含了所需要的Castle组件(External-Bin/Net/2.0/Castle.DynamicProxy.dll),但是我们的目标是让我们编译出来的IBatisNet、Castle能完美的集成,而且我们下载的IBatisNet包与Castle包中都包含了log4net,不过版本不同。为了IBatisNet、Castle的完美集成,同时也为了统一log4net的版本,我们首先编译Castle,用得到的Castle.DynamicProxy.dll覆盖IBastisNet包中的Castle.DynamicProxy.dll,同时用Castle包中的log4net替换IBatisNet包中的log4net。然后编译IBastisNet,最后用编译出来的IBastisNet替换Castle中的IBastisNet部件,最终让Castle集成IBastisNet.DataMapper 1.5。

  • 编译Castle

    编译Castle需要使用nant,具体的编译方法参见Castle根目录下的How to build.txt,我们的编译指令是:

    nant -D:nhibernate.test=false -D:activerecord.test=false - -D:monorail.test=false

    因为我们不使用nhibernate和monorail,因此忽略测试过程以减少编译时间。
     
  • 编译IBatisNet

    将前面编译得到的Castle.DynamicProxy.dll从Castle/build/net-2.0拷贝到/iBatis.Net/External-Bin/Net/2.0目录下(覆盖),同时将Castle/SharedLibs/log4net下的log4net.dll拷贝到/iBatis.Net/External-Bin/Net/2.0下(覆盖)。

    打开iBatis.Net根目录下的IBatisNet.2005.sln,编译IBatisNet.DataMapper。
     
  • 再次编译Castle

    用前面编译得到的IBatisNet.DataMapper替换Castle包中的IBatisNet.DataMapper组件。具体说,将刚刚编译得到的

    IBatisNet.Common.dll
    IBatisNet.Common.Logging.Log4Net.dll
    IBatisNet.DataMapper.dll

    拷贝到Castle/SharedLibs/ibatis(覆盖).

      重新编译Castle,编译指令不变

      nant -D:nhibernate.test=false -D:activerecord.test=false - -D:monorail.test=false

    如果编译出来的是Debug版的,将来调试的时候就可以跟踪到IBatisNet和Castle的源代码中。经过上面的过程,现在已经得到了IBatisNet+Castle+Castle.MVC的可执行组件,其中Castle.MVC位于Castle/Sandbox/MVC目录中。下面就来搭建WEB框架。

 

2.3 搭建Castle+IBatisNet+Castle.MVC构架

    这里通过一个简单的WEB项目来演示Castle+IBatisNet+Castle.MVC的搭建过程。假设我们要创建一个live站点,在Visual Studio.NET中创建一个基于文件系统的liveWEB网站项目。项目的初始状态如图:

 

下面,在此工程基础上建立起Castle+IBatisNet+Castle.MVC架构。

  1. 引入Castle

    我们主要使用Castle.Windsor。首先我们给工程增加一个WEB配置文件:web.config,如图



    将Castle集成的IBatisNet引进工程,给工程添加引用时,选择Castle.Windsor.dll,得到



    下面配置,在web.config中增加如下代码配置Castle.Windsor,

    增加一个全局应用程序类来初始化Castle.Windsor



    全局类在Global.asac.cs中实现,他的一个重要任务就是实例化项目中唯一的WindsorContainer实例。关键代码如下:

    private static IWindsorContainer _container;

    void Application_Start(object sender, EventArgs e)
    {
        _container = new Castle.Windsor.WindsorContainer("liveApp.xml");

    }

    然后给Global增加一个静态属性以便项目中其他地方能方面的获得该WindsorContainer实例。

    public static IWindsorContainer Container
    {
        get
        {
            return _container;
        }
    }

    这样项目中任何地方都可以通过Global.Container访问项目中全局唯一的WindsorContainer实例。项目中获取WindsorContainer实例的方法多种多样,我们仅给出一个最简单的例子。

    上面WindsorContainer实例化时我们用一个配置文件liveApp.xml来初始化该实例。该文件非常重要,它是Castle的配置文件。具体到我们这里,其内容如下:

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

    <facilities>

    </configuration>

    目前,他还是一个空的配置文件,随着构架的完善,该配置文件中将增加相应的配置信息。liveApp.xmlWEB项目的根目录下即可。

    为测试WindsorContainer是否能正常工作,对Application_Start稍做修改,如下:

    void Application_Start(object sender, EventArgs e)
    {
        _container = new Castle.Windsor.WindsorContainer("liveApp.xml");
        _container.AddComponent("TestComponent", typeof(Object), typeof(Object));

    }

    加粗的代码在容器中增加一个对象,并命名为TestComponent。然后我们再Default.aspx.cs中获取TestComponent对象,如下:

    protected void Page_Load(object sender, EventArgs e)
    {
        Object obj = Global.Container["TestComponent"] as Object;
        if (obj != null)
            this.Label_Message.Text = "Castle.WindsorContainer works!"
        else
            this.Label_Message.Text = "Canstle.Windsortaner does not work yet!"
    }


    编译并浏览Default.aspx,结果如下:

     

    至此,Castle可以工作了。回顾上面的过程可以发现,引入Castle的过程是很简单的。下面引进IBatisNet。

     

  2. 将Castle集成的IBatisNet引进工程

    这里描述引入IBatisNet的方法。Castle集成IBatisNet能带很多好处,我们认为最重要的是基于Castle的AOP的事物管理方式,这种方式允许我们采用类似COM+和EJB那样的声明式的方式描述事物。下面说明如果配置Castle以引入IBatisNet。

    前面再编译Castle与IBatisNet的时候,已经将我们编译好的IBatisNet组件复制到Castle包中,下面只需要配置Castle即可将IBatisNet引入工程。

    首先,我们为工程"添加引用"为引入IBatisNet做好准备。引入以下项目:

    Castle.Facilities.AutomaticTransactionManagement.dll
    Castle.Services.Transaction.dll
    Castle.Facilities.IBatisNetIntegration.dll
    IBatisNet.DataMapper.dll

    然后配置Castle已集成IBatisNet,具体说就是在liveApp.xml中增加配置,修改后,liveApp.xml的内容如下:

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

    <facilities>

    <facility id="iBatisNet" >
        <sqlMap id="sqlMap" config="sqlMap.config"/>
    </facility>

    </configuration>

    上面蓝色文件对IBatisNet的配置,这样Castle就将IBatisNet集成到项目中来,同时指定了IBatisNet的配置文件为sqlMap.config。现在IBatisNet已经被Castle管理起来,项目中任何地方可通过如下方式访问sqlMap:

    SqlMapper sqlMap = Windsor.Container["sqlMap"] as SqlMapper;

    由于SqlMapper实例被Castle管理起来,IBatisNet的使用被简化。

    关于IBatisNet具体如何配置与使用,请参见IBatisNet的文档,关键在sqlMap.config中,这里不细说。


  3. 将Castle.MVC引进工程

    至此Castle+IBatisNet框架已经搭建起来。下面搭建MVC框架。

    ASP.NET的WebForm使用虽然简单,但其架构不清晰,相比asp、php这样的纯脚本模式虽然进步不少,却还是容易导致混乱。Castle.MVC为ASP.NET引入MVC架构,同时保留了WebForm的灵活性,我们认为是一个很适合ASP.NET的架构。

    为引入Castle.MVC,首先将Castle.MVC.dll(在Castle/Sandbox/MVC中)引入到项目中来,然后在liveApp.xml中增加相应的配置内容,修改后,liveApp.xml的内容如下:

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

    <facilities>

    <facility id="iBatisNet" >
    <sqlMap id="sqlMap" config="../tour.persistence/sqlMap.config"/>
    </facility>

    <facility id="MVCFacility" type="Castle.MVC.MVCFacility, Castle.MVC" >
    <assembyView></assembyView>
    </facility>
    </facilities>

    </configuration>

    蓝色内容为新增内容。然后,我们在web.config中为Castle.MVC增加相应的配置,首先增加一个configSection,如下:

    <?xml version="1.0"?>
    <configuration xmlns="
    http://schemas.microsoft.com/.NetConfiguration/v2.0">

    <configSections>
    <section name="mvc" type="Castle.MVC.Configuration.ConfigurationSectionHandler, castle.mvc"/>
    </configSections>

    ...

    上面蓝色部分加在<configuration>节点之后,web.config其他配置代码之前。

     

    下面再为MVC增加配置块(web.config中)

    <mvc>
    <webViews>
        <view id="Default" path="Default.aspx"/>
    </webViews>
    <global-commands>
        <command id="goHome" view="Default"/>
    </global-commands>
    <command-mappings>
    </command-mappings>
    </mvc>

 

    至此,live项目中Castle+IBatisNet+Castle.MVC的架构已经搭建起来,关于Castle、IBatisNet的配置有专门的文章进行介绍,请参阅。关于MVC的配置,目前没有资料可参考,我们目前是根据源码学习的,以后资料整理出来再交流。

    该架构目前已经应用在我们的项目中,感觉改架构层次清晰,使用方便、灵活,值得推荐。