海水正藍

          面朝大海,春暖花開
          posts - 145, comments - 29, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
          對依賴注入( http://www.oschina.net/code/snippet_871522_15682) 的進一步加強.
          作為基本功能的注冊,使用語法是:registration.register<Interface,Implementation>().
          可以到了實際的項目中,要注冊的接口和類可能不止一個兩個,會成百上千。無論是用C#代碼來注冊,還是用XML文件來配置,都是開發(fā)者的噩夢。

          這里,讓我們來個思維的反轉: 變集中配置為分散聲明。
          1 為要注冊的類,加入RegisterInContainer的聲明
          2 在系統(tǒng)啟動的時候,掃描所有的類,對有RegisterInContainer的類,找到它所有實現(xiàn)的接口,把這些接口和該類綁定注冊。

          用于裝飾要注入類的Attribute.


           1 using System;
           2 using System.Linq;
           3 using Skight.eLiteWeb.Domain.BasicExtensions;
           4 
           5 namespace Skight.eLiteWeb.Domain.Containers
           6 {
           7     [AttributeUsage(AttributeTargets.Class)]
           8     public class RegisterInContainerAttribute : Attribute
           9     {
          10         public RegisterInContainerAttribute(LifeCycle life_cycle) {
          11             this.life_cycle = life_cycle;
          12         }
          13 
          14         public LifeCycle life_cycle { getset; }
          15         public Type type_to_register_in_container { getset; }
          16 
          17         public void register_using(Registration registration) {
          18             DiscreteItemResolver resolver = new TypeResolver(type_to_register_in_container);
          19             if (life_cycle == LifeCycle.singleton) resolver = new SingletonResolver(resolver);
          20             registration.register(resolver,type_to_register_in_container.all_interface().ToArray());
          21         }
          22     }
          23 }

          注入聲明Attribute參數(shù),指定是否單件方式生成注冊類。


          1 namespace Skight.eLiteWeb.Domain.Containers
          2 {
          3     public enum LifeCycle
          4     {
          5         single_call,
          6         singleton
          7     }
          8 }

          注冊聲明Attribute的使用示例


           1 //調用Container.get_an<FrontController>()將會得到FrontControllerImpl的對象
           2 
           3 using Skight.eLiteWeb.Domain.Containers;
           4 
           5 namespace Skight.eLiteWeb.Presentation.Web.FrontControllers
           6 {
           7     [RegisterInContainer(LifeCycle.single_call)]
           8     public class FrontControllerImpl : FrontControllers.FrontController
           9     {
          10         private CommandResolver command_resolver;
          11 
          12         public FrontControllerImpl(CommandResolver commandResolver)
          13         {
          14             command_resolver = commandResolver;
          15         }
          16 
          17         public void process(WebRequest request)
          18         {
          19             command_resolver.get_command_to_process(request).process(request);
          20         }
          21     }
          22 }

          Registration添加一個方法:反過來,為一個解析器(實現(xiàn)類)注冊多個接口。


          1 void register(DiscreteItemResolver resolver, params Type[] contracts);
          2 

          掃描注冊機,在系統(tǒng)啟動時調用一次。


           1 using System.Collections.Generic;
           2 using System.Reflection;
           3 using Skight.eLiteWeb.Domain.BasicExtensions;
           4 using Skight.eLiteWeb.Domain.Containers;
           5 
           6 namespace Skight.eLiteWeb.Application.Startup
           7 {
           8     public class RegistrationScanner:StartupCommand
           9     {
          10         private readonly Registration registration;
          11         private readonly IEnumerable<Assembly> assemblies;
          12 
          13         public RegistrationScanner(Registration registration, params Assembly[] assemblies)
          14         {
          15             this.registration = registration;
          16             this.assemblies = assemblies;
          17         }
          18 
          19         public void run()
          20         {
          21             assemblies
          22                 .each(assembly =>
          23                       assembly.GetTypes()
          24                               .each(type =>
          25                                     type.run_againste_attribute<RegisterInContainerAttribute>(
          26                                         attribute =>
          27                                             {
          28                                                 attribute.type_to_register_in_container = type;
          29                                                 attribute.register_using(registration);
          30                                             })));
          31         }
          32     }
          33 }

          系統(tǒng)啟動:創(chuàng)建注冊類,然后傳入必要的Assembly,調用注冊機注冊所有加了Attribute的類。


           1 using System;
           2 using System.Collections.Generic;
           3 using System.Reflection;
           4 using Skight.eLiteWeb.Domain.Containers;
           5 using Skight.eLiteWeb.Presentation.Web.FrontControllers;
           6 
           7 namespace Skight.eLiteWeb.Application.Startup
           8 {
           9     public class ApplicationStartup
          10     {
          11         public void run()
          12         {
          13             var registration = create_registration();
          14             new RegistrationScanner(registration,
          15                                                Assembly.GetAssembly(typeof (Container)),
          16                                                Assembly.GetAssembly(typeof (FrontController)),
          17                                                Assembly.GetAssembly(typeof (StartupCommand)))
          18                                                .run();
          19 
          20         }
          21 
          22         private Registration create_registration()
          23         {
          24             IDictionary<Type, DiscreteItemResolver> item_resolvers = new Dictionary<Type, DiscreteItemResolver>();
          25             Container.initialize_with(new ResolverImpl(item_resolvers));
          26             return new RegistrationImpl(item_resolvers);
          27         }
          28     }
          29 }

          Global.asax系統(tǒng)入口,把所有的代碼串起來。


           1 <%@ Application Language="C#" %>
           2 <%@ Import Namespace="Skight.eLiteWeb.Application.Startup" %>
           3 <script  RunAt="server">
           4 
           5     private void Application_Start(object sender, EventArgs e)
           6     {
           7        new ApplicationStartup().run();
           8     }
           9 
          10 </script>

          原文出自:
          http://www.oschina.net/code/snippet_871522_16735
          主站蜘蛛池模板: 海南省| 林口县| 包头市| 荣成市| 卓资县| 邮箱| 盐城市| 米林县| 瓦房店市| 无棣县| 新和县| 新河县| 鄂托克旗| 溧水县| 嘉善县| 黎城县| 伊金霍洛旗| 抚州市| 深圳市| 沐川县| 潜山县| 定州市| 玛纳斯县| 金堂县| 鹤岗市| 水城县| 大港区| 石门县| 达尔| 罗源县| 拉孜县| 许昌县| 丽江市| 五常市| 万州区| 洱源县| 宜兰县| 克什克腾旗| 富平县| 金昌市| 榆中县|