IoC(控制反轉)是時下很流行的設計模式,它可以大大的簡少程式之間的相依性,有點像工廠模式,在Class中操作的都是Interface,而Interface與Class的對應與建立實例都是由IoC Framework處理,光是在.Net Framework下的IoC Framework就有近10套,每套都有各自的優缺點,呼叫方式也略有不同,切換IoC Framework是非常麻煩的,或是開發組件(Assembly),組件也是使用IoC,但是又不能限制使用端用特定款IoC Framework,這時候可以考慮使用IoC的中繼器:CommonServiceLocator來解決這個問題。
NOTE:
IoC的文章很多人寫,而且也寫的非常完整與詳細,小弟就不在這裡多述,各位可以參考以下文章:
In 91 : [Software Architecture]IoC and DI
什麼是CommonServiceLocator
官方網址:http://commonservicelocator.codeplex.com/
CommonServiceLocator是放在Codeplex中由Microsoft patterns & practices團隊所設計的小組件,它很輕所有的Code才一百多行,它主要的定義一些Interface,讓我們的程式是呼叫CommonServiceLocator,透過CommonServiceLocator去呼叫IoC Framework,如同中繼器一般,使我們的程式不會綁死於一同IoC Framework,而且有提供主流的IoC Framework用的Provider(就算未提供也可以自己寫),支援非常的廣泛。
支援的IoC Framework如下:
- Castle Windsor
- Spring .NET
- Unity
- StructureMap
- Autofac
- MEF
- LinFu
使用方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //泛型 //第一個Method,也是最常用的Method ICreditCardService instance = ServiceLocator.Current.GetInstance<ICreditCardService>(); //第二個多載Method,因為一個Interface,所能有很多個Class實作,如果有設定Key,可以用Key指定要實例的Type ICreditCardService instance = ServiceLocator.Current.GetInstance<ICreditCardService>( "中國信託" ); //非泛型的 ICreditCardService instance = (ICreditCardService)ServiceLocator.Current.GetInstance( typeof (ICreditCardService)); ICreditCardService instance = (ICreditCardService)ServiceLocator.Current.GetInstance( typeof (ICreditCardService), "中國信託" ); //從System.IServiceProvider繼承來的,不過看了幾個Provider,GetService都只是呼叫GetInstance,所以沒什麼不同 ICreditCardService instance = (ICreditCardService)ServiceLocator.Current.GetService( typeof (ICreditCardService)); |
註冊Provider
1 2 3 4 5 6 7 8 | //先註冊IoC的東西 ContainerBuilder builder = new ContainerBuilder(); builder.RegisterType<OrderService>().As<IOrderService>(); builder.RegisterType<中國信託CreditCardService>().Named<ICreditCardService>( "中國信託" ); builder.RegisterType<台北富邦CreditCardService>().Named<ICreditCardService>( "台北富邦" ); //最後在設定Provider ServiceLocator.SetLocatorProvider(() => new MyServiceLocator(builder)); |
這裡介紹幾個常見的IoC設定方式,詳情請看官方網站的說明。
Autofac的設定
到Autofac網站下載AutofacContrib,加入參考AutofacContrib.CommonServiceLocator.dll
1 2 3 | ContainerBuilder builder = new ContainerBuilder(); var container = builder.Build(); ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(container)); |
Spring .NET的設定
下載:CommonServiceLocator.SpringAdapter.zip,加入參考CommonServiceLocator.SpringAdapter.dll
1 2 3 4 5 | DefaultListableObjectFactory objectFactory = new DefaultListableObjectFactory( false ); objectFactory.RegisterSingleton( typeof (SimpleLogger).FullName, new SimpleLogger()); objectFactory.RegisterSingleton( typeof (AdvancedLogger).FullName, new AdvancedLogger()); ServiceLocator.SetLocatorProvider(() => new SpringServiceLocatorAdapter(objectFactory)); |
Unity的設定
下載:CommonServiceLocator.UnityAdapter.zip,加入參考Microsoft.Practices.Unity.ServiceLocatorAdapter.dll
1 2 3 4 5 6 7 | IUnityContainer container = new UnityContainer() .RegisterType<ILogger, AdvancedLogger>() .RegisterType<ILogger, SimpleLogger>( typeof (SimpleLogger).FullName) .RegisterType<ILogger, AdvancedLogger>( typeof (AdvancedLogger).FullName); ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container)); return new UnityServiceLocator(container); |
StructureMap的設定
下載:CommonServiceLocator.StructureMapAdapter.zip,加入參考StructureMapAdapter.dll
1 2 3 4 5 6 7 | Registry registry = new Registry(); registry.ForRequestedType<ILogger>().TheDefaultIsConcreteType<AdvancedLogger>(); registry.AddInstanceOf<ILogger>( new SimpleLogger()).WithName( typeof (SimpleLogger).FullName); registry.AddInstanceOf<ILogger>( new AdvancedLogger()).WithName( typeof (AdvancedLogger).FullName); IContainer container = new Container(registry); ServiceLocator.SetLocatorProvider(() => new StructureMapServiceLocator(container)); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?