EnterLib ObjectBuild vs Castle WindsorContainer, part 1

來源:互聯網
上載者:User
首先來看一下在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, null, null);

    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, null, null);
     
        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)的注入方式,在此不再舉例。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.