使用IBatisNet + Castle 开发DotNet软件

        本文主要讲述我在项目中如何使用IBatisNet + Castle的结构来进行开发的。软件的主框架如下图:
    

       我将系统分为五层,分别是Domain,Persistence,Service,Component,Web。系统的分层参考了NPetShop2的结构并稍加简化。下面简单说明一下每一层的功能:

Domain -- 业务实体层
Persistence -- 持久层,负责数据访问
Service -- 服务层,调用持久层方法并实现业务逻辑
Web -- 最终展现给客户的Web界面,调用Service层方法
Componet -- 主要包括一些通用的方法等

      系统使用了Castle.Facilities,Castle.IOC以及IBatisNet,IBatisNet的DataMapper是通过Castle来管理的,下面分别介绍每一部分的配置及使用:

一、IBatisNet的配置
        参见:IBatisNet1.5--配置篇

二、IBatisNet Facility 和 AutomaticTransactionManagement Facility配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  
<facilities>

    
<facility id="ibatis" type="Castle.Facilities.IBatisNetIntegration.IBatisNetFacility, Castle.Facilities.IBatisNetIntegration" >
      
<sqlMap id="sqlServerSqlMap" config="SqlMap.config" />
    
</facility>

    
<facility id="transaction" type="Castle.Facilities.AutomaticTransactionManagement.TransactionFacility, Castle.Facilities.AutomaticTransactionManagement" />

  
</facilities>

</configuration>

三、IOC的配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  
<components>
    
<component
            
id="insititution"
            service
="FES.Service.Interfaces.IInstitutionService, FES.Service"
            type
="FES.Service.InsititutionService, FES.Service" />
  
</components>

</configuration>

目前IOC的配置还可支持泛型,详细请参考:
福 娃    [Castle]Castle也范型

当这些配置文件都写好之后,我们还需将其加载到Castle容器当中,具体的代码可写在Global.asax文件。
Global

这样我们的配置才算完成,然后可以在代码中使用这些组件了。

四、将asp.net页面加入到Castle容器中
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

using System.Web;
using System.Web.Security;
using System.Reflection;
using System.Data;
using System.Configuration;
using Castle.Core;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;

namespace FES.Component
{
    
/// <summary>
    
/// 为将ASP.NET页面添加到Castle容器中而建立的类,所有页面必须继承此类
    
/// </summary>

    public class PageBase : System.Web.UI.Page
    
{
        
protected BindingFlags BINDING_FLAGS_SET
                    
= BindingFlags.Public
                    
| BindingFlags.SetProperty
                    
| BindingFlags.Instance
                    
| BindingFlags.SetField
                    ;

        
protected override void OnInit(EventArgs e)
        
{
            IWindsorContainer container 
= ObtainContainer();

            Type type 
= this.GetType();

            PropertyInfo[] properties 
= type.GetProperties(BINDING_FLAGS_SET);

            
foreach (PropertyInfo propertie in properties)
            
{
                
string pname = propertie.Name;

                
if (container.Kernel.HasComponent(pname))
                
{
                    propertie.SetValue(
this, container[pname], null);
                }

            }


            
base.OnInit(e);
        }



        
public IWindsorContainer ObtainContainer()
        
{

            IContainerAccessor containerAccessor 
=

            HttpContext.Current.ApplicationInstance 
as IContainerAccessor;
            
if (containerAccessor == null)
            
{
                
throw new ApplicationException("你必须在HttpApplication中实现接口 IContainerAccessor 暴露容器的属性");
            }


            IWindsorContainer container 
= containerAccessor.Container;
            
if (container == null)
            
{
                
throw new ApplicationException("HttpApplication 得不到容器的实例");
            }

            
return container;
        }

    }

}

 
五、从Castle容器中得到ISqlMapper的实例
       本系统将IBatisNet交给Castle来管理,所以ISqlMapper的实例也必须从Castle容器中获取,这样Castle才能真正的管理IBatisNet。
       首先我们需要一个得到容器实例的方法:
/// <summary>
        
/// Obtain the Windsor container.
        
/// </summary>
        
/// <returns></returns>

        public static IWindsorContainer GetContainer()
        
{
            IContainerAccessor containerAccessor 
= HttpContext.Current.ApplicationInstance as IContainerAccessor;

            
if (containerAccessor == null)
            
{
                
throw new ApplicationException("你必须在HttpApplication中实现接口 IContainerAccessor 暴露容器的属性");
            }


            IWindsorContainer container 
= containerAccessor.Container;

            
if (container == null)
            
{
                
throw new ApplicationException("HttpApplication 得不到容器的实例");
            }


            
return container;
        }

从容器中获得ISqlMapper实例的方法:
/// <summary>
        
/// IsqlMapper实例,从Castle容器中获取
        
/// </summary>
        
/// <returns></returns>

        public static ISqlMapper sqlMap = (ContainerAccessorUtil.GetContainer())["sqlServerSqlMap"as ISqlMapper;
        

其中"sqlServerSqlMap"即是在我们配置IBatisNet Facility时指定的。

五、在Service层中使用事务处理
using System;
using System.Collections.Generic;
using System.Text;

using FES.Persistence;
using FES.Model;
using FES.Service.Interfaces;

using Castle.Services.Transaction;
using Castle.Facilities.IBatisNetIntegration;

namespace FES.Service
{
    [Transactional]
    [UsesAutomaticSessionCreation]
    
public class InsititutionService : IInstitutionService
    
{
        
IInstitutionService Members
    }

}


写的很简单,希望高手指点。。。
      

posted on 2007-01-04 13:15 Daniel Pang 阅读(3331) 评论(17)  编辑 收藏 所属分类: CastleIBatisNetASP.NET2.0

评论

#1楼  2007-01-23 11:18 Matt Yeung      

我最近也在研究IBatisNet + Castle的开发,我曾经为WEBFORM 的DI发愁,很高兴看到你的解决方案,对我帮助很大,不知道你有否看到过IHTTPHANDLER的方案,不知道你的想法如何
http://forum.castleproject.org/viewtopic.php?p=5241&sid=1fd76d34cd41eb357b4693e74f41f055

https://svn.sourceforge.net/svnroot/cuyahoga/trunk/Web/HttpHandlers/PageHandler.cs

  回复  引用  查看    

#2楼 [楼主] 2007-01-28 21:53 Daniel Phang      

@Matt Yeung
很高兴和你一起交流IBatisNet & Castle的开发问题。   回复  引用  查看    

#3楼  2007-04-10 16:13 flyingchen      

将ib交给castle管理,带来的好处是?请教:)
用您编写的那个mapper类,不也一样吗?   回复  引用  查看    

#4楼 [楼主] 2007-04-11 10:00 Daniel Pang      

@flyingchen
使用Castle中的事务管理可以将数据访问和业务逻辑分开   回复  引用  查看    

#5楼  2007-05-16 15:31 goodq [未注册用户]

public IWindsorContainer ObtainContainer()
{

IContainerAccessor containerAccessor =

HttpContext.Current.ApplicationInstance as IContainerAccessor;
if (containerAccessor == null)
{
throw new ApplicationException("你必须在HttpApplication中实现接口 IContainerAccessor 暴露容器的属性");
}

IWindsorContainer container = containerAccessor.Container;
if (container == null)
{
throw new ApplicationException("HttpApplication 得不到容器的实例");
}
return container;
}

这咱做的好处是什么呢,还有的是这种如果做单元测试,怎么办呢,单元测试他没法模拟httpcontext的环境的   回复  引用    

#6楼 [楼主] 2007-05-18 10:20 Daniel Pang      

/// <summary>
/// 得到容器中的服务
/// </summary>
/// <param name="name">服务名</param>
/// <returns></returns>
public object GetService(string name)
{
IWindsorContainer container = new WindsorContainer(new XmlInterpreter(new ConfigResource()));
return container[name];
}
单元测试中,可以用上面的方法   回复  引用  查看    

#7楼  2007-06-14 22:51 条码,条形码,条码打印机,条码扫瞄枪,标签,碳带,条码解决方案 [未注册用户]

大哥,真的看不懂,能不能写的简单些,我可是刚刚学啊   回复  引用    

#8楼  2007-06-26 22:59 jianyi0115      

有点疑问:
[Transaction(TransactionMode.Requires)]
public void NewDepartmentAndEmployee(Employee emp,int did)
{
_institution.NewEmployee(emp,did);
_institution.NewDepartment(null);

}
这样可以实现事务控制吗?
Castle IOC实现声明式的事务控制应该是采用动态代理的拦截吧??
Castle的动态代理不是要求函数必须是虚函数吗??
判解答:jianyi0115@163.com   回复  引用  查看    

#9楼  2007-06-27 08:13 flyingchen [未注册用户]

实现接口的也ok的   回复  引用    

#10楼  2007-09-23 01:02 无处坏      

LZ可以发一份你的框架的代码给我学习啊,小弟也正在学习这两个开源的相关反技术,谢谢,我的email:wqjch@163.com ,msn:wisliqj@hotmailcom   回复  引用  查看    

#11楼  2007-11-02 00:10 马海军 [未注册用户]

如果代码是可以申请的,请给我发一份,谢谢!!   回复  引用    

#12楼  2008-08-11 14:21 大李      

能不能发一份代码的demo给我呢,最近想学习ibatis架构   回复  引用  查看    


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-01-04 13:25 编辑过
 
 


<2007年1月>
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910

导航

统计

公告

技术交流平台,真诚的希望能和园子里的朋友交流技术,共同进步!
欢迎加入Castle+IBatisNet交流群:2923364(已满),37745404
特别提示:本站文章若无特别申明,均为原创,转载请注明出自'博客园'!
Emailpwei013#163.com
MSNshypw520#gmail.com

与我联系

搜索

 

常用链接

留言簿(10)

我参与的团队

随笔分类(98)

随笔档案(74)

相册

收藏夹(19)

MY BLOG

公司主页

情侣BLOG

友情链接

积分与排名

最新随笔