当前访客身份:游客 [ 登录 | 加入开源中国 ]

代码分享

当前位置:
代码分享 » C#  » 常用工具方法
分享到: 
收藏 +0
2

代码片段(12) [全屏查看所有代码]

1. [代码]Container注入框架的进入点     跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [全屏预览]

namespace Skight.LightWeb.Domain
{
    public class Container
    {
        private static Resolver underlying_resolver;
        public static Resolver Current
        {
            get { return underlying_resolver; }
        }
        public static T get_a<T>()
        {
            return underlying_resolver.get_a<T>();
        }

        public static void initialize_with(Resolver resolver)
        {
            underlying_resolver = resolver;
        }
    }
}

2. [代码]Container的实现核心,依赖解析器的接口定义。(接口名称,我不加I,故意的)     跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [全屏预览]

using System;

namespace Skight.LightWeb.Domain
{
    public interface Resolver
    {
        Dependency get_a<Dependency>();
        object get_a(Type type);
    }
}

3. [代码]依赖解析器的测试 (使用Machine Specification)     跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [全屏预览]

using System;
using System.Collections.Generic;
using Machine.Specifications;
using Rhino.Mocks;

namespace Skight.LightWeb.Domain.Specs
{
    public class When_bind_a_class_to_a_intefercate
    {
        private Establish context =
            () =>
                {
                    var item_resolver = MockRepository.GenerateMock<DiscreteItemResolver>();
                    var dictioary = new Dictionary<Type, DiscreteItemResolver>();
                    dictioary.Add(typeof (MockInterface), item_resolver);
                    subject = new ResolverImpl(dictioary);
                    item_resolver.Stub(x => x.resolve()).Return(new MockImplementaion());
                };

       private It should_resolve_the_interface_to_the_class =
            () => subject.get_a<MockInterface>().ShouldBeOfType<MockImplementaion>();

        private static ResolverImpl subject;
        private interface MockInterface { }
        private class MockImplementaion : MockInterface { }
        
    }   
}

4. [代码]解构器的实现     跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [全屏预览]

using System;
using System.Collections.Generic;

namespace Skight.LightWeb.Domain
{
    public class ResolverImpl:Resolver
    {
        private readonly IDictionary<Type, DiscreteItemResolver> item_resolvers;

        public ResolverImpl(IDictionary<Type, DiscreteItemResolver> itemResolvers)
        {
            item_resolvers = itemResolvers;
        }

        public Dependency get_a<Dependency>()
        {
            return (Dependency) item_resolvers[typeof (Dependency)].resolve();
        }

        public object get_a(Type type)
        {
            return item_resolvers[type].resolve();
        }
    }
}

5. [代码]注册器的接口定义 (是的,先要注册才能解析,可是业务视图却是反的)     跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [全屏预览]

namespace Skight.LightWeb.Domain
{
    public interface Registration
    {
        void register<Contract, Implementaion>() where Implementaion : Contract;
    }
}

6. [代码]注册器的的测试     跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [全屏预览]

using System;
using System.Collections.Generic;
using Machine.Specifications;

namespace Skight.LightWeb.Domain.Specs
{
    public class When_use_Registration_to_register_an_infterface_to_a_class
    {
        private Establish context =
            () =>
                {
                    resolver_dictionary = new Dictionary<Type, DiscreteItemResolver>();
                    subject = new RegistrationImpl(resolver_dictionary);
                    
            };

        private Because of =
            () => subject.register<MockInterface, MockImplementation>();

        private It the_key_value_pair_should_be_added_to_resovler_dictionary =
            () => resolver_dictionary[typeof (MockInterface)].resolve().ShouldBeOfType<MockImplementation>();
        
        private static RegistrationImpl subject;
        private static Dictionary<Type, DiscreteItemResolver> resolver_dictionary;

        private interface MockInterface{}
        private class MockImplementation:MockInterface {}
    }
}

7. [代码]注册器的的实现     跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [全屏预览]

using System;
using System.Collections.Generic;

namespace Skight.LightWeb.Domain
{
    public class RegistrationImpl:Registration
    {
        private IDictionary<Type, DiscreteItemResolver> item_resolvers;
        public RegistrationImpl(IDictionary<Type, DiscreteItemResolver> item_resolvers)
        {
            this.item_resolvers = item_resolvers;
        }

        public void register<Contract, Implementation>() where Implementation : Contract
        {
           
            item_resolvers.Add(typeof(Contract), new TypeResolver(typeof(Implementation)));
        }
    }

}

8. [代码]具体解构器接口定义 (命名:离散解构器,可以看作是对象工厂的一种形式)     跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [全屏预览]

namespace Skight.LightWeb.Domain
{
    public interface DiscreteItemResolver
    {
        object resolve();
    }
}

9. [代码]离散解构器的测试     跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [全屏预览]

using System;
using Machine.Specifications;
using Rhino.Mocks;

namespace Skight.LightWeb.Domain.Specs
{
    public class TypeResolverSpecs
    {
        protected static TypeResolver subject;
    }

    public class given_a_simple_type_which_has_a_parameterless_constructor
        : TypeResolverSpecs
    {
        private Establish context =
            () => subject = new TypeResolver(typeof (SimpleType));

        private It should_create_object_from_class =
            () => subject.resolve().ShouldBeOfType<SimpleType>();

        protected class SimpleType{}
    }

    public class given_a_complex_type_whose_constructor_need_other_types
       : TypeResolverSpecs {
        private Establish context =
            () =>
                {
                    var resolver = MockRepository.GenerateMock<Resolver>();
                    Container.initialize_with(resolver);
                    resolver.Stub(x => x.get_a(Arg<Type>.Is.Equal(typeof (SimpleType))))
                        .Return(new SimpleType());

                    subject = new TypeResolver(typeof (ComplexType));
            };

        private It should_create_object_from_class =
            () => subject.resolve().ShouldBeOfType<ComplexType>();

        protected class SimpleType{}
        protected class ComplexType
        {
            private SimpleType simple;

            public ComplexType(SimpleType simple)
            {
                this.simple = simple;
            }
        }
    }
}

10. [代码]离散解构器的实现 (有递归,如果该类构造器有接口参数的,需要用Container解构)     跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [全屏预览]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Skight.LightWeb.Domain
{
    public class TypeResolver:DiscreteItemResolver
    {
        private readonly Type type_to_create;

        public TypeResolver(Type type_to_create)
        {
            this.type_to_create = type_to_create;
        }

        public object resolve()
        {
            ParameterInfo[] param_types = get_constructor_parameters();
            IEnumerable<object> parameters = get_parameters(param_types);
            return Activator.CreateInstance(type_to_create, parameters.ToArray());
        }

        private IEnumerable<object> get_parameters(ParameterInfo[] param_types)
        {
            return param_types.Select(x => Container.Current.get_a(x.ParameterType));
        }

        private ParameterInfo[] get_constructor_parameters()
        {
            var constructor= type_to_create.GetConstructors()
                .OrderByDescending(x => x.GetParameters().Count())
                .First();
            return constructor.GetParameters();
        }
    }
}

11. [代码]集成测试,完整地用例。     跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [全屏预览]

using System;
using System.Collections.Generic;
using Machine.Specifications;

namespace Skight.LightWeb.Domain.Specs
{
    public class DependencyIntegrationSpecs
    {
        private Establish context =
            () =>
                {
                    IDictionary<Type, DiscreteItemResolver> item_resolvers = new Dictionary<Type, DiscreteItemResolver>();
                    registration = new RegistrationImpl(item_resolvers);
                    Container.initialize_with(new ResolverImpl(item_resolvers));
                    
                };

        protected static Registration registration;
    }

    public class when_registry_a_simple_class_RepositoryImpl_without_further_dependency:DependencyIntegrationSpecs
    {
        private Establish context =
            () => registration.register<Repository, RepositoryImpl>();
        private Because of =
           () => result = Container.get_a<Repository>();

        private It should_get_a_object_which_is_not_null =
            () => result.ShouldNotBeNull();

        private It should_get_RepositoryImpl_class =
            () => result.ShouldBeOfType<RepositoryImpl>();

        private static Repository result;
    }

    public class when_registry_a_class_ServiceImpl_which_depend_on_another_interface_Repository : DependencyIntegrationSpecs {
        private Establish context =
            () => {
                registration.register<Repository, RepositoryImpl>();
                registration.register<Service,ServiceImpl>();
            };
        private Because of =
           () => result = Container.get_a<Service>();

        private It inject_repository_should_not_be_null =
            () => result.ShouldNotBeNull();

        private It should_inject_service =
            () => result.ShouldBeOfType<ServiceImpl>();

        private It should_inject_repository_into_service =
            () => result.Repository.ShouldBeOfType<RepositoryImpl>();
        

        private static Service result;
    }
    public interface Repository { }
    public class RepositoryImpl : Repository { }
    public interface Service{Repository Repository { get; } }
    public class ServiceImpl : Service
    {
        private Repository repository;

        public ServiceImpl(Repository repository)
        {
            this.repository = repository;
        }

        public Repository Repository
        {
            get { return repository; }
        }
    }
}

12. [代码]Bootstrapper系鞋带代码,把所有的碎片组合起来,作为Web,在Gloable.asax中调用     跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [全屏预览]

using System;
using System.Collections.Generic;
using Skight.LightWeb.Domain;
using Skight.LightWeb.Presentation.Web.FrontController;


namespace Skight.LightWeb.Application.Startup
{
    public class ApplicationStartup
    {
        public void run()
        {
            IDictionary<Type, DiscreteItemResolver> item_resolvers = new Dictionary<Type, DiscreteItemResolver>();
            Container.initialize_with(new ResolverImpl(item_resolvers));
            var registration = new RegistrationImpl(item_resolvers);
            registration.register<Repository,RepositoryImpl>();
            registration.register<FrontController,FrontControllerImpl>();
            registration.register<CommandResolver,CommandResolverImpl>();
            
        }

        /// <summary>
        /// Test purpose class an interface
        /// </summary>
        public interface Repository { }
        public class RepositoryImpl : Repository { }
    }
}


开源中国-程序员在线工具:Git代码托管 API文档大全(120+) JS在线编辑演示 二维码 更多»

发表评论 回到顶部 网友评论(31)

  • 1楼:假正经哥哥 发表于 2012-11-22 09:11 回复此评论
    看了半天没看明白 是我水平有问题?
  • 2楼:予沁安 发表于 2012-11-22 09:23 回复此评论
    哪一部分不明白?
  • 3楼:予沁安 发表于 2012-11-22 09:24 回复此评论

    引用来自“假正经哥哥”的评论

    看了半天没看明白 是我水平有问题?
    哪一部分?
  • 4楼:假正经哥哥 发表于 2012-11-22 09:42 回复此评论

    引用来自“予沁安”的评论

    引用来自“假正经哥哥”的评论

    看了半天没看明白 是我水平有问题?
    哪一部分?
    不说别的就说这个吧,一个函数里面连续的两个return return Activator.CreateInstance(type_to_create, parameters.ToArray()); return Activator.CreateInstance(type_to_create);
  • 5楼:予沁安 发表于 2012-11-22 10:41 回复此评论

    引用来自“假正经哥哥”的评论

    引用来自“予沁安”的评论

    引用来自“假正经哥哥”的评论

    看了半天没看明白 是我水平有问题?
    哪一部分?
    不说别的就说这个吧,一个函数里面连续的两个return return Activator.CreateInstance(type_to_create, parameters.ToArray()); return Activator.CreateInstance(type_to_create);
    已经修改,请查收 :),谢谢。
  • 6楼:予沁安 发表于 2012-11-22 11:46 回复此评论

    引用来自“假正经哥哥”的评论

    引用来自“予沁安”的评论

    引用来自“假正经哥哥”的评论

    看了半天没看明白 是我水平有问题?
    哪一部分?
    不说别的就说这个吧,一个函数里面连续的两个return return Activator.CreateInstance(type_to_create, parameters.ToArray()); return Activator.CreateInstance(type_to_create);
    还有其他的吗?
  • 7楼:假正经哥哥 发表于 2012-11-22 14:10 回复此评论
    再看了几次总算看明白了,是构造函数注入的实现 。以后能不能接口用I开头啊。否则看的忒累 
     

    另外类似
      private Because of =

        () => result = Container.get_a<Service>();


    这样的语法...Because 是个类型  of 是个变量? 然后这个类型是个委托?
    这样的代码看着好吃力啊
  • 8楼:予沁安 发表于 2012-11-22 23:45 回复此评论

    引用来自“假正经哥哥”的评论

    再看了几次总算看明白了,是构造函数注入的实现 。以后能不能接口用I开头啊。否则看的忒累 
     

    另外类似
      private Because of =

        () => result = Container.get_a<Service>();


    这样的语法...Because 是个类型  of 是个变量? 然后这个类型是个委托?
    这样的代码看着好吃力啊
    谢谢,不敢说你是唯一也是少数几个,看完代码,并回复的人. 关于,你说的两个问题,恰恰是我的改进,从而推崇的. 其实,在这之前,我应该出个前传. :) 之前的很厂的时间, 主要精力在代码和架构本身. 这里, 只是简单的把代码放出来, 肯定是不够的. 可是,完善是一个迭代的过程, 抛砖引玉, 更希望大家的帮助. 这其实是开源的本质. 关于两个问题, 以下在分别讨论.
  • 9楼:予沁安 发表于 2012-11-23 00:38 回复此评论

    引用来自“假正经哥哥”的评论

    再看了几次总算看明白了,是构造函数注入的实现 。以后能不能接口用I开头啊。否则看的忒累 
     

    另外类似
      private Because of =

        () => result = Container.get_a<Service>();


    这样的语法...Because 是个类型  of 是个变量? 然后这个类型是个委托?
    这样的代码看着好吃力啊
    * 接口命名要不要加前缀I ? 匈牙利命名已经逐渐在废弃, 不是主流,至少在.Net和Java等面向业务应用的平台是如此. 可是, .Net中,唯有接口成了最后的遗少. 跳出我们的习惯思维, 这不是一个很奇怪的事情吗? 从业务建模的角度, 当我使用Resolver时,我并不关心,他是Interface , abstract class 还是concrete class. 甚至,我以后都会在这几种类型切换,修改。所以,对他的命名,只体现他的业余含义,而不需要技术含义。否则, 就是一个混合的怪胎。
  • 10楼:予沁安 发表于 2012-11-23 00:45 回复此评论

    引用来自“假正经哥哥”的评论

    再看了几次总算看明白了,是构造函数注入的实现 。以后能不能接口用I开头啊。否则看的忒累 
     

    另外类似
      private Because of =

        () => result = Container.get_a<Service>();


    这样的语法...Because 是个类型  of 是个变量? 然后这个类型是个委托?
    这样的代码看着好吃力啊
    Because语法,是Machine Specification. 涉及到几个方面: 1. Lamda表达式, 2。 测试的AAA语法(Arrange ==> Establish, Action ==> Because, Assert ==>It ) 3. 行为驱动 (BDD) 对一个场景的测试描述,一般如下: When.... Becuase of .... It should be.... 可以看到,描述中关键词在代码中的出现。 当然, 这是一个很大的话题,很大的变化。
  • 11楼:予沁安 发表于 2012-11-23 00:54 回复此评论

    引用来自“假正经哥哥”的评论

    再看了几次总算看明白了,是构造函数注入的实现 。以后能不能接口用I开头啊。否则看的忒累 
     

    另外类似
      private Because of =

        () => result = Container.get_a<Service>();


    这样的语法...Because 是个类型  of 是个变量? 然后这个类型是个委托?
    这样的代码看着好吃力啊
    考虑普及一下 MSpec. 先参考: http://www.cnblogs.com/lipu/archive/2010/11/17/machine_specifications.html http://codebetter.com/aaronjensen/2008/05/08/introducing-machine-specifications-or-mspec-for-short/
  • 12楼:天地一少鸥 发表于 2012-11-23 10:03 回复此评论
    悲哀,C#忘了好多。。。
  • 13楼:mmpp33 发表于 2012-11-27 09:33 回复此评论
    看见变量里面有"_"就头痛,看起来特不爽。
  • 14楼:寻找爱玩Tom 发表于 2012-11-28 09:02 回复此评论
    老兄,能不能打个包上传。。。
  • 15楼:予沁安 发表于 2012-11-28 10:16 回复此评论

    引用来自“浪子剑客”的评论

    老兄,能不能打个包上传。。。
    http://www.oschina.net/p/lightweb
  • 16楼:予沁安 发表于 2012-11-28 10:31 回复此评论

    引用来自“mmpp33”的评论

    看见变量里面有"_"就头痛,看起来特不爽。
    _是用来取代空格,更具可读性。 比较三个,那个更能一眼看懂? thisistest ThisIsTest This is test.
  • 17楼:帖子列表 发表于 2012-11-28 21:33 回复此评论
    PHPer表示完全看不懂,IoC居然要用这么多代码来实现
  • 18楼:桔子 发表于 2012-11-29 11:05 回复此评论
    oo害死人呀,用oo就不要说整洁了
  • 19楼:予沁安 发表于 2012-11-30 12:49 回复此评论

    引用来自“李马燕”的评论

    PHPer表示完全看不懂,IoC居然要用这么多代码来实现
    汗,这代码多吗? 哪一个IOC 不都几乎是一个独立的项目来着。你不全认为这是怎么使用Ioc吧!
  • 20楼:予沁安 发表于 2012-11-30 12:51 回复此评论

    引用来自“桔子”的评论

    oo害死人呀,用oo就不要说整洁了
    整洁的东西都害人。不谈oo,递归也曾经害了不少人吧!