• Castle~实现IoC容器


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

    运行的结果为:

    感谢您的阅读!

  • 相关阅读:
    linux学习 建立静态库,动态库,写简单的makefile
    C++中顶层const和底层const
    BDB (Berkeley DB)数据库简单介绍(转载)
    Java中Map的使用
    Spring MVC 3 深入总结
    nvl,空时的推断和取值
    java堆栈 (转)
    mybatis--面向接口编程
    HDU 4888
    socket编程——一个简单的样例
  • 原文地址:https://www.cnblogs.com/lori/p/2861407.html
Copyright © 2020-2023  润新知