使用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配置
三、IOC的配置
目前IOC的配置还可支持泛型,详细请参考:
福 娃 [Castle]Castle也范型
当这些配置文件都写好之后,我们还需将其加载到Castle容器当中,具体的代码可写在Global.asax文件。
这样我们的配置才算完成,然后可以在代码中使用这些组件了。
四、将asp.net页面加入到Castle容器中
五、从Castle容器中得到ISqlMapper的实例
本系统将IBatisNet交给Castle来管理,所以ISqlMapper的实例也必须从Castle容器中获取,这样Castle才能真正的管理IBatisNet。
首先我们需要一个得到容器实例的方法:
从容器中获得ISqlMapper实例的方法:
其中"sqlServerSqlMap"即是在我们配置IBatisNet Facility时指定的。
五、在Service层中使用事务处理
写的很简单,希望高手指点。。。
我将系统分为五层,分别是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>
<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>
<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;
}
}
}
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;
}
/// 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;
/// 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
}
}
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 阅读(6697) 评论(14) 编辑 收藏 举报