项目开发在各个层中通过接口实现松耦合的时候,如何实现接口调用接口实现类?
这里的要求是接口有多个实现类,通过接口调用不的接口实现类!
开始,我想到了IOC(IOC最近忒火),确实有很多开发好的类库unity,ninject等等,但是这些类库都有点太强大了,例
如unity 是可以很容易实现我的要求,那么通过RegisterType<I, N>>(String name)注册;通过Resolve<I>(name) 就可以
用接口调用相应的接口实现类,如果想了解一下unity,
http://www.cnblogs.com/scy251147/archive/2012/11/21/2781328.html的文章不错!
但是我想要的也就这点功能,所以就没有必要引入第三方库,自己实现一下IOC【其实,我对IOC理解比较肤浅,我的理解就是同
一接口调用接口的不同实现类(多态),所以下面不敢用IOC命名】,我这里定义为ServiceFactory类,另一个帮助类ServiceKey;
接口IOrderService和实现IOrderService接口的OrderService类OrderService2类。
1 /// <summary> 2 /// 根据服务接口创建服务类工厂 3 /// </summary> 4 public class ServiceFactory 5 { 6 7 /// <summary> 8 /// 容器(唯一键,服务标志) 9 /// </summary> 10 private static Dictionary<String, RuntimeTypeHandle> container; 11 12 /// <summary> 13 /// 静态构造函数(注册接口) 14 /// </summary> 15 static ServiceFactory() 16 { 17 container = new Dictionary<String, RuntimeTypeHandle>(); 18 19 RegisterType<IOrderService, OrderService>(); 20 RegisterType<IOrderService, OrderService2>(ServiceKey.Second);/*同一接口,多个实现类*/ 21 } 22 23 /// <summary> 24 /// 注册对应服务接口和服务类型 25 /// </summary> 26 /// <typeparam name="I">服务接口</typeparam> 27 /// <typeparam name="T">服务类型</typeparam> 28 /// <param name="Key">服务的key</param> 29 private static void RegisterType<I, T>(ServiceKey Key = ServiceKey.First) 30 where I : class 31 where T : class 32 { 33 String name = typeof(I).FullName; 34 name += ((Int32)Key).ToString(); 35 container.Add(name, typeof(T).TypeHandle); 36 } 37 38 /// <summary> 39 /// 根据服务接口创建服务类型 40 /// </summary> 41 /// <typeparam name="I">服务接口类型</typeparam> 42 /// <param name="Key">服务的key(默认ServiceKey.First,用于同一接口,多个实现类)</param> 43 /// <returns>服务类型实例</returns> 44 public static I Create<I>(ServiceKey Key = ServiceKey.First) where I : class 45 { 46 Type newType = Type.GetTypeFromHandle(container[typeof(I).FullName + ((Int32)Key).ToString()]); 47 return System.Activator.CreateInstance(newType) as I; 48 } 49 }
1 /// <summary> 2 /// 服务的key(用于根据服务接口创建服务类,特别同一接口,多个实现类) 3 /// </summary> 4 public enum ServiceKey 5 { 6 First = 1, 7 Second = 2, 8 Third = 3, 9 Fourth = 4, 10 Fifth = 5, 11 Sixth = 6, 12 Seventh = 7, 13 Eighth = 8, 14 Ninth = 9 15 }
1 public interface IOrderService 2 { 3 String Test(); 4 } 5 6 class OrderService : IOrderService 7 { 8 9 private String info = "OrderService"; 10 public OrderService() 11 { 12 info += DateTime.Now.ToString(); 13 } 14 public String Test() 15 { 16 return info; 17 } 18 } 19 20 class OrderService2 : IOrderService 21 { 22 private String info = "OrderService2"; 23 public OrderService2() 24 { 25 info += DateTime.Now.ToString(); 26 } 27 public String Test() 28 { 29 return info; 30 } 31 }
1、RegisterType方法:添加接口和对应的实现类的标志(RuntimeTypeHandle 是类型唯一的抽象标志)到字典容器container中
2、Create方法:根据接口创建接口类型的实例,【这里接口就关联上了接口实现类】,保证在调用前都有注册接口,所以所有的注册
接口都放在静态构造函数中
3、参数ServiceKey为接口实现类的唯一键,通过接口的FullName+ServiceKey就可以唯一标示,接口有多个实现类的时候是关键
4、单元测试
1 [TestMethod] 2 public void TestServiceFactory() 3 { 4 var t11 = ServiceFactory.Create<IOrderService>().Test(); 5 var t12 = ServiceFactory.Create<IOrderService>().Test(); 6 var t13 = ServiceFactory.Create<IOrderService>().Test(); 7 var t21 = ServiceFactory.Create<IOrderService>(ServiceKey.Second).Test(); 8 var t22 = ServiceFactory.Create<IOrderService>(ServiceKey.Second).Test(); 9 } 10
这里,我们手动来维护接口和实现类的关联,大大增加了灵活性和项目的自主控制力,同时也实现了接口多态和解耦!