工欲善其事,必先利其器——Castle

工欲善其事,必先利其器——Castle

Castle 是针对. NET 平台的一个非常优秀的开源项目,从数据访问框架ORM(Object-Relational Mapping ,对象关系映射)到IOC( Inversion of Control ,控制反转或者叫依赖注入) 容器,再到WEB 层的MVC 框架、AOP,基本包括了整个开发过程中的所有东西,为开发易扩展、可伸缩、灵活、健壮的软件系统提供了一个很好的平台,为我们快速的构建企业级的应用程序提供了很好的服务。

Castle 包括Castle ActiveRecord 和Castle IOC 容器。

Castle ActiveRecord 是一个O/R(对象持久化) 工具。在面向对象的开发中,数据访问层最基本的数据库操作包括插入对象、删除对象、更新对象和查询对象,几乎所有的项目开发中都需要把这些数据库操作用数据库语言select 、delete 、insert 、update 等SQL 语句实现。而使用传统的ADO. NET 技术操作数据库,会使系统的业务逻辑和数据访问混合在一起,导致系统各个层之间有很强的耦合度,不易于扩展和维护。使用O/ R 工具实现了数据库操作从传统SQL 模式到基于对象模式的转换和业务逻辑层与数据访问层分离,提高了系统开发对数据库的透明度和开发效率。Castle ActiveRecord 为ORM 提供对象持久、关系对象查询、简单事务处理、简单异常管理等功能。数据持久包括一些对象的Insert 、Delete、Update、Ret rieve 等功能,关系对象查询则提供一些基于对象的复杂关系查询,包括对应到数据库功能的子查询、关联查询(JOIN) 、函数支持(count 、avg、max、min) 、聚合等。使用ORM 工具完全隔离了对数据库的直接操作,使开发人员将主要时间去关注业务逻辑。框架涉及到的关键技术主要有:透明的持久对象层;客户端应用对象空间与数据库服务器端元组空间的映射。

 

Castle IOC是一个IOC 工具。Windsor是Castle的一个IOC(依赖注入) 容器。它构建于Micro Kernel 之上,功能非常强大,能检测类并了解使用这些类时需要什么参数,检测类型和类型之间的工作依赖性,并提供服务或者发生错误时提供预警的机制。

 

下面是一篇转载的文章:

IOC的容器确实不少,unity,autofac,Castle 等等,前两种组件如何实现IOC在我之前的文章中已经做过说明了,今天主要来说一下Castle如何去实现IoC,事实上Castle是小微的一个开源项目,最早接触它是在orchard项目中,在orchard里主要用在动态代理方法拦截上,当然这是castle最重要的作用,事实上它当然也可以实现IoC了,不过,你要下载一个Castle.Windsor.dll,它主要实现ioc功能的。

说干就干,事情和前两个组件的工作场景是相似的,一个irepository,多种实现方式,ef,linq,nhibernate,ado.net等等,你可以根据你的需要去实现它,这只是最大层次上的多态,代码可能是这样:

泛型类版本

 

 1 #region 泛型注入

 2     public interface IRepository<T>

 3     {

 4         void Insert(T entity);

 5     }

 6

 7     public class EFRepository<T> : IRepository<T>

 8     {

 9         #region IRepository<T> 成员

10

11         public void Insert(T entity)

12         {

13             Console.WriteLine("EFRepository泛型注入" + entity);

14         }

15

16         #endregion

17     }

18  #endregion

 

非泛型版本(泛型方法版本)

 

 1 #region 非泛型注入

 2     public interface IRepository

 3     {

 4         void Insert<T>(T entity);

 5     }

 6

 7     public class EFRepository : IRepository

 8     {

 9         #region IRepository<T> 成员

10

11         public void Insert<T>(T entity)

12         {

13             Console.WriteLine("EFRepository非泛型注入" + entity);

14         }

15

16         #endregion

17     }

18

19     public class LINQRespository : IRepository

20     {

21         #region IRepository<T> 成员

22

23         public void Insert<T>(T entity)

24         {

25             Console.WriteLine("LINQRepository非泛型注入" + entity);

26         }

27

28         #endregion

29     }

30     #endregion

 

对于这两种类型,在castle配置上也略有不同,看代码:

      <component   id="非泛型"   service="Test.IRepository,Test"   type="Test.EFRepository,Test" />

      <component   id="泛型"   service="Test.IRepository`1,Test"   type="Test.EFRepository`1,Test" />

上面的代码是架构层次的,而对于具体的业务,如用户方面的业务可能有多个版本的考虑,可能有代缓存的,不代缓存的,可能有发邮件的,也可能有发短信的,这是具体业务层次的多态,代码可能是这样的:

 

 1 #region 服务是泛型,类型不是泛型

 2

 3     public interface IMessageService<T>

 4     {

 5         void Sending(T entity);

 6     }

 7     public class UserService : IMessageService<User>

 8     {

 9

10

11         #region IMessageService<User> 成员

12

13         public void Sending(User entity)

14         {

15             Console.WriteLine("用户模块发消息,采用E-Mail方式");

16         }

17

18         #endregion

19     }

20

21     public class ProductService : IMessageService<Product>

22     {

23         #region IMessageService<Product> 成员

24

25         public void Sending(Product entity)

26         {

27             Console.WriteLine("产品模块发消息采用短信");

28         }

29

30         #endregion

31     }

32     #endregion

 

看上面的代码,一个发消息的业务,它对于不同的业务对象,可能有不同的实现方式,而这种方法,我们可以在配置文件中进行设置:

1       <component   id="具体业务,接口为泛型,实现非泛型"   service="Test.IMessageService`1[[Test.User,Test]],Test" 
      type="Test.UserService,Test" />

整個配置文件內容如下:

 

<configuration>

  <configSections>

    <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>

  </configSections>

  <castle>

    <components>

      <component   id="非泛型"   service="Test.IRepository,Test"   type="Test.EFRepository,Test" />

      <component   id="泛型"   service="Test.IRepository`1,Test"   type="Test.EFRepository`1,Test" />

      <component   id="具体业务,接口为泛型,实现非泛型"   service="Test.IMessageService`1[[Test.User,Test]],Test"   type="Test.UserService,Test" />

 

    </components>

  </castle>

</configuration>

 

而castle容器的代码也封装了一下,改了上人的低版本的,呵呵 

 

    /// <summary>

    /// IOC容器

    /// </summary>

    public sealed class Container

    {

        #region Fields & Properies

        /// <summary>

        /// WindsorContainer object

        /// </summary>

        private WindsorContainer windsor;

        private IKernel kernel;

        public IKernel Kernel

        {

            get { return kernel; }

        }

 

        /// <summary>

        /// 容器实例

        /// </summary>

        private static readonly Container instance = new Container();

        public static Container Instance

        {

            get { return Container.instance; }

        }

 

        #endregion

 

        #region Constructors

        /// <summary>

        /// Constructor Method.

        /// Initialization IOC.

        /// </summary>

        public Container()

        {

            try

            {

                Castle.Core.Resource.ConfigResource source = new Castle.Core.Resource.ConfigResource();

                XmlInterpreter interpreter = new XmlInterpreter(source);

                windsor = new WindsorContainer(interpreter);

                kernel = windsor.Kernel;

            }

            catch (Exception)

            {

                throw;

            }

        }

        #endregion

 

        #region Public Methods

        /// <summary>

        /// Returns a component instance by the type of service.

        /// </summary>

        /// <typeparam name="T"></typeparam>

        /// <returns></returns>

        public T Resolve<T>()

        {

            return kernel.Resolve<T>();

        }

        /// <summary>

        /// Release resource that be container used.

        /// </summary>

        public void Dispose()

        {

            kernel.Dispose();

        }

        #endregion

 

        #region Private Methods

        /// <summary>

        /// Returns a component instance by the service name.

        /// </summary>

        /// <param name="service"></param>

        /// <returns></returns>

        private object Resolve(Type service)

        {

            return kernel.Resolve(service);

        }

 

        /// <summary>

        /// Returns a component instance by the service name.

        /// </summary>

        /// <param name="key"></param>

        /// <returns></returns>

        private object Resolve(String key)

        {

            return kernel.Resolve<object>(key);

        }

        #endregion

 

    }

 

在程序中调用它的代码为:

 

        IRepository iRepository = Container.Instance.Resolve<IRepository>();

            iRepository.Insert<User>(new User { Name = "ok" });

 

            IRepository<User> iRepository1 = Container.Instance.Resolve<IRepository<User>>();

            iRepository1.Insert(new User { Name = "ok" });

 

            IMessageService<User> r = (IMessageService<User>)Container.Instance.Resolve<IMessageService<User>>();

            r.Sending(new User { Name = "ok" });

 

运行的结果为:

 

感谢您的阅读!

 

posted @ 2015-11-06 10:11  _King  阅读(194)  评论(0编辑  收藏  举报