zoukankan      html  css  js  c++  java
  • EnterLib ObjectBuild vs Castle WindsorContainer

    首先来看一下在Castle项目中用于示范其Ioc功能的一个小例子:



       
    1:  public interface IEmailSender
       
    2:  {
       
    3:      void Send(String from, String to, String message);
       
    4:  }

       
    5:   
       
    6:  public interface ITemplateEngine
       
    7:  {
       
    8:      String Process(String templateName);
       
    9:  }

      
    10:   
      
    11:  public interface INewsletterService
      
    12:  {
      
    13:      void Dispatch(String from, String[] targets, String message);
      
    14:  }

      
    15:   
      
    16:  public class SmtpEmailSender : IEmailSender
      
    17:  {
      
    18:      private String _host;
      
    19:      private int _port;
      
    20:   
      
    21:      public SmtpEmailSender(String host, int port)
      
    22:      {
      
    23:          _host = host;
      
    24:          _port = port;
      
    25:      }

      
    26:   
      
    27:      public virtual void Send(String from, String to, String message)
      
    28:      {
      
    29:          Console.WriteLine("Sending e-mail from {0} to {1} with '{2}'"
      
    30:              from, to, message );
      
    31:      }

      
    32:  }

      
    33:   
      
    34:  public class NVelocityTemplateEngine : ITemplateEngine
      
    35:  {
      
    36:      public virtual String Process(String templateName)
      
    37:      {
      
    38:          return "Some template content";
      
    39:      }

      
    40:  }

      
    41:   
      
    42:  public class SimpleNewsletterService : INewsletterService
      
    43:  {
      
    44:      private IEmailSender _sender;
      
    45:      private ITemplateEngine _templateEngine;
      
    46:   
      
    47:      public SimpleNewsletterService
      
    48:          (IEmailSender sender, ITemplateEngine templateEngine)
      
    49:      {
      
    50:          _sender = sender;
      
    51:          _templateEngine = templateEngine;
      
    52:      }

      
    53:   
      
    54:      public void Dispatch(String from, String[] targets, String message)
      
    55:      {
      
    56:          String msg = _templateEngine.Process(message);
      
    57:   
      
    58:          foreach(String target in targets)
      
    59:          {
      
    60:              _sender.Send(from, target, msg);
      
    61:          }

      
    62:      }

      
    63:   
      
    64:  }


    Ioc的作用就是能够利用容器自动的构建出一个SimpleNewsletterService对象,而不是由用户直接的创建并传递其参数,这样就可以进一步降低对象与对象之间耦合程度,从而方便的替换其实现。在上例中将采用构造器设值的方式,来实现对象依赖关系的注入。下面给出Castle的实现方式:

    BasicUsage.xml
    <?xml version="1.0" encoding="utf-8" ?> 
    <configuration>
        
    <components>
            
    <component id="smtpemailsender">
                
    <parameters>
                    
    <host>localhost</host>
                    
    <port>110</port>
                
    </parameters>
            
    </component>
        
    </components>
    </configuration>



       
    1:  public static void Main()
       
    2:  {
       
    3:      IWindsorContainer container = 
       
    4:      new WindsorContainer( new XmlInterpreter("../BasicUsage.xml") );
       
    5:   
       
    6:      container.AddComponent( "newsletter"
       
    7:          typeof(INewsletterService), typeof(SimpleNewsletterService) );
       
    8:      container.AddComponent( "smtpemailsender"
       
    9:          typeof(IEmailSender), typeof(SmtpEmailSender) );
      
    10:      container.AddComponent( "templateengine"
      
    11:          typeof(ITemplateEngine), typeof(NVelocityTemplateEngine) );
      
    12:   
      
    13:      String[] friendsList = new String[] "john""steve""david" };
      
    14:   
      
    15:      // Ok, start the show
      16:   
      
    17:      INewsletterService service = 
      
    18:          (INewsletterService) container["newsletter"];
      
    19:      service.Dispatch("hammett at gmail dot com",
      
    20:                                friendsList, "merryxmas");
      
    21:  }


    不断向容器中加入各种类型的对象,加入过程中容器自动建立起它们之间的依赖关系,最后当我们从容器取出对象的时候,就是已经配置好依赖关系的对象。以上就是Castle的工作模式,不过Castle中的配置过程过于透明,在你完全意料不到的情况下,对象的依赖关系就按照对象被注入容器的先后顺序被设定了。非常的自动,非常的透明带来的就是某些时候的莫名奇妙。

    再来看看ObjectBuild的实现方式,首先你需要通过属性(Attibute)或者配置文件的方式显式的设定依赖关系:


      
    42:  public class SimpleNewsletterService : INewsletterService
      
    43:  {
      
    44:      private IEmailSender _sender;
      
    45:      private ITemplateEngine _templateEngine;
      
    46:   
      
    47:      public SimpleNewsletterService(
      
    48:              [Dependency(CreateType = typeof(SmtpEmailSender))]
      
    49:              IEmailSender sender, 
      
    50:              [Dependency(CreateType = typeof(NVelocityTemplateEngine))] 
      
    51:              ITemplateEngine templateEngine)
      
    52:      {
      
    53:          _sender = sender;
      
    54:          _templateEngine = templateEngine;
      
    55:      }

      
    56:   
      
    57:      public void Dispatch(String from, String[] targets, String message)
      
    58:      {
      
    59:          String msg = _templateEngine.Process(message);
      
    60:   
      
    61:          foreach(String target in targets)
      
    62:          {
      
    63:              _sender.Send(from, target, msg);
      
    64:          }

      
    65:      }

      
    66:   
      
    67:  }
     
     

    然后再利用Build直接的构造出对象

    public static void Main(string[] args)
    {
        
    string config = string.Format(
          
    @"<object-builder-config xmlns='pag-object-builder'>
            <build-rules>
                <build-rule type='{0}' mode='Singleton'>
                  <mapped-type type='{1}'/>                            
                  <constructor-params>
                     <value-param type='System.String'>localhost</value-param>
                     <value-param type='System.Int32'>110</value-param>
                  </constructor-params>
                </build-rule>
             </build-rules>
            </object-builder-config>
    ", FullNameIEmailSender, FullNameSmtpEmailSender);

        Builder builder 
    = new Builder(ObjectBuilderXmlConfig.FromXml(config));
        Locator locator 
    = CreateLocator();

        INewsletterService newsletterService 
    =
           builder.BuildUp
    <SimpleNewsletterService>(locator, nullnull);

        String[] friendsList 
    = new String[] "john""steve""david" };

        
    // Ok, start the show

        newsletterService.Dispatch(
    "hammett at gmail dot com",
                                      friendsList, 
    "merryxmas");
    }


    从以上我们可以看出
    1.  ObjectBuild和Sping类似,需要显式指定依赖关系,不过多出通过Attribute来指定的方式,而Castle则依赖于特定的对象注入顺序。可以说各有优缺点,但是我prefer前者,安全第一。(Castle也提供了在配置文件中显式指定的方式。)
    2.  ObjectBuild支持直接创建临时对象,而不注入容器。(注意在上面的代码中我们仅仅BuildUp了SimpleNewsletterService,而没有象Castle那样还要将SimpleNewsletterService所依赖的对象也注入容器。)其实在OB中你可以选择是否将对象注入容器,通常情况下Singleton类型的对象才被注入容器。
    3.  相对与Castle容器的概念,ObjectBuild如同它的名字所示,更象是一个构建器,你可以通过它来构建任意的对象,这些对象可能会被注入容器,也可能仅仅是一个临时对象,不过在对象的创建过程中你可以加入很多的控制,让它更符合你的需求。
    4. 相对而言Castle Ioc的使用更加简洁,而ObjectBuild更加复杂一些(其实比较它们构建对象所需要的语句,OB需要的更少,只是OB的API还不够简洁,需要再做些包装),不过ObjectBuild的定制扩展能力也是相当强大,比如以上通过配置文件和属性(Attribute)结合的配置方式,完全可以通过OB中提供的API搞定,下面就是采用全编程方式的实现:
        
    public static void Main()
        
    {

            Builder builder 
    = new Builder();
            Locator locator 
    = CreateLocator();
            
            builder.Policies.SetDefault
    <ISingletonPolicy>(new SingletonPolicy(true));
            
            ConstructorPolicy policy 
    = new ConstructorPolicy();
            policy.AddParameter(
    new ValueParameter<string>("localhost"));
            policy.AddParameter(
    new ValueParameter<int>(110));

            builder.Policies.Set
    <ICreationPolicy>
                (policy, 
    typeof(SmtpEmailSender), null);
            builder.Policies.Set
    <ITypeMappingPolicy>
                (
    new TypeMappingPolicy(typeof(SmtpEmailSender), null), 
                 
    typeof(IEmailSender), null);

            builder.Policies.Set
    <ITypeMappingPolicy>
                (
    new TypeMappingPolicy(typeof(NVelocityTemplateEngine), null), 
                 
    typeof(ITemplateEngine), null);

            ConstructorPolicy policy2 
    = new ConstructorPolicy();
            policy2.AddParameter(
    new CreationParameter(typeof(IEmailSender)));
            policy2.AddParameter(
    new CreationParameter(typeof(ITemplateEngine)));
            builder.Policies.Set
    <ICreationPolicy>
                (policy2,
    typeof(SimpleNewsletterService),null); 


            INewsletterService newsletterService 
    =
                 builder.BuildUp
    <SimpleNewsletterService>(locator, nullnull);
          
            String[] friendsList 
    = new String[] "john""steve""david" };

            
    // Ok, start the show

            newsletterService.Dispatch(
    "hammett at gmail dot com"
                                       friendsList, 
    "merryxmas");
        }


    5. Castle Ioc和ObjectBuild都支持属性设值(Property Setter)的注入方式,在此不再举例。

  • 相关阅读:
    _STORAGE_WRITE_ERROR_:./Application/Runtime/Cache/Home/f8995a0e1afcdadc637612fae5a3b585.php
    git 报错:没有权限 remote: error: unable to unlink old 'README.md' (Permission denied)
    深度学习入门实战(二)-用TensorFlow训练线性回归
    一条SQL搞定信息增益的计算
    Vue.js动画在项目使用的两个示例
    腾讯云安全:开发者必看|Android 8.0 新特性及开发指南
    腾讯云上Selenium用法示例
    一个只有99行代码的JS流程框架
    腾讯云上PhantomJS用法示例
    前端开发框架简介:angular和react
  • 原文地址:https://www.cnblogs.com/tommyli/p/1204074.html
Copyright © 2011-2022 走看看