Castle~实现IoC容器

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:

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" });

运行的结果为:

感谢您的阅读!

本文转自博客园张占岭(仓储大叔)的博客,原文链接:Castle~实现IoC容器,如需转载请自行联系原博主。

目录
相关文章
|
5月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
4月前
|
XML Java 开发者
经典面试---spring IOC容器的核心实现原理
作为一名拥有十年研发经验的工程师,对Spring框架尤其是其IOC(Inversion of Control,控制反转)容器的核心实现原理有着深入的理解。
182 3
|
3月前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
91 0
|
5月前
|
XML Java 数据格式
Spring5入门到实战------5、IOC容器-Bean管理(三)
这篇文章深入探讨了Spring5框架中IOC容器的高级Bean管理,包括FactoryBean的使用、Bean作用域的设置、Bean生命周期的详细解释以及Bean后置处理器的实现和应用。
Spring5入门到实战------5、IOC容器-Bean管理(三)
|
5月前
|
XML Java 数据格式
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
这篇文章是Spring5框架的入门教程,详细讲解了IOC容器中Bean的自动装配机制,包括手动装配、`byName`和`byType`两种自动装配方式,并通过XML配置文件和Java代码示例展示了如何在Spring中实现自动装配。
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
|
5月前
|
XML Java 数据格式
Spring5入门到实战------2、IOC容器底层原理
这篇文章深入探讨了Spring5框架中的IOC容器,包括IOC的概念、底层原理、以及BeanFactory接口和ApplicationContext接口的介绍。文章通过图解和实例代码,解释了IOC如何通过工厂模式和反射机制实现对象的创建和管理,以及如何降低代码耦合度,提高开发效率。
Spring5入门到实战------2、IOC容器底层原理
|
5月前
|
XML Java 数据格式
Spring5入门到实战------8、IOC容器-Bean管理注解方式
这篇文章详细介绍了Spring5框架中使用注解进行Bean管理的方法,包括创建Bean的注解、自动装配和属性注入的注解,以及如何用配置类替代XML配置文件实现完全注解开发。
Spring5入门到实战------8、IOC容器-Bean管理注解方式
|
1月前
|
监控 NoSQL 时序数据库
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
260 77
|
9天前
|
Ubuntu NoSQL Linux
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
77 6
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
|
1月前
|
监控 Docker 容器
在Docker容器中运行打包好的应用程序
在Docker容器中运行打包好的应用程序