小木猫

 找回密码
 立即注册

扫一扫,访问微社区

搜索
热搜: 活动 交友 discuz
查看: 2206|回复: 6
打印 上一主题 下一主题

ServiceLocator and Unity – Be Careful

[复制链接]

373

主题

1055

帖子

5657

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5657
跳转到指定楼层
楼主
发表于 2015-8-23 10:06:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Jeremiah.Clark 12 May 2009 3:00 PM

http://blogs.msdn.com/b/miah/arc ... ity-be-careful.aspx

Chris Tavarez has provided a handy adapter (UnityServiceLocator) for using ServiceLocator to resolve types from a Unity container.  You can then use ServiceLocator.SetLocatorProvider() to register the UnityServiceLocator as the default provider for ServiceLocator.

For this example, we will be using ServiceLocator and Unity to resolve the type IFoo to Foo using a singleton lifetime.  Then we will get two instances of IFoo and compare to ensure that they are the same object.

Here are four different approaches to configuring ServiceLocator and Unity that I have found during my searches on the web:

1:

   1: static void Main(string[] args)
   2: {            
   3:     UnityServiceLocator locator = new UnityServiceLocator(ConfigureUnityContainer());
   4:     ServiceLocator.SetLocatorProvider(() => locator);
   5:  
   6:     var a = ServiceLocator.Current.GetInstance<IFoo>();
   7:     var b = ServiceLocator.Current.GetInstance<IFoo>();
   8:  
   9:     Console.WriteLine(a.Equals(b));            
  10: }
  11:  
  12: private static IUnityContainer ConfigureUnityContainer()
  13: {
  14:     UnityContainer container = new UnityContainer();
  15:     container.RegisterType<IFoo, Foo>(new ContainerControlledLifetimeManager());
  16:     return container;
  17: }
2:

   1: static void Main(string[] args)
   2: {      
   3:     ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(ConfigureUnityContainer()));
   4:  
   5:     var a = ServiceLocator.Current.GetInstance<IFoo>();
   6:     var b = ServiceLocator.Current.GetInstance<IFoo>();
   7:  
   8:     Console.WriteLine(a.Equals(b));            
   9: }
  10:  
  11: private static IUnityContainer ConfigureUnityContainer()
  12: {
  13:     UnityContainer container = new UnityContainer();
  14:     container.RegisterType<IFoo, Foo>(new ContainerControlledLifetimeManager());
  15:     return container;
  16: }
3:

   1: static void Main(string[] args)
   2: {
   3:     UnityContainer container = new UnityContainer();
   4:     container.RegisterType<IFoo, Foo>(new ContainerControlledLifetimeManager());
   5:  
   6:     ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container));
   7:  
   8:     var a = ServiceLocator.Current.GetInstance<IFoo>();
   9:     var b = ServiceLocator.Current.GetInstance<IFoo>();
  10:  
  11:     Console.WriteLine(a.Equals(b));            
  12: }
4:

   1: static void Main(string[] args)
   2: {
   3:     UnityContainer container = new UnityContainer();
   4:     container.RegisterType<IFoo, Foo>(new ContainerControlledLifetimeManager());
   5:     UnityServiceLocator locator = new UnityServiceLocator(container);
   6:     
   7:     ServiceLocator.SetLocatorProvider(() => locator);
   8:  
   9:     var a = ServiceLocator.Current.GetInstance<IFoo>();
  10:     var b = ServiceLocator.Current.GetInstance<IFoo>();
  11:  
  12:     Console.WriteLine(a.Equals(b));            
  13: }


So these implementations seem to to do the same basic thing: register the UnityServiceLocator and use it to resolve types.  But…

howardpayne

Pop quiz:
Can you find the subtle differences and explain the problems that they can cause?

Explanation:
Example #1:  This implementation works as expected.  The two instances (a and b) reference the same container controlled object.

Example #2:  This one is just wrong.  The two instances are not the same object, but two distinct objects.  Since the argument for the SetLocatorProvider() method is a delegate, each call to ServiceLocator.Current executes the delegate again, creating a new Unity container for every call.  This one also has the same side effect as #3.

Example #3:  This one gives the correct behavior with respect to instances a and b, but leads to a new UnityServiceLocator object being created for each ServiceLocator.Current call.  This could lead to a lot of objects just hanging around until the GC runs and reclaims the memory.

Example #4:  Works as expected.  Essentially the same as #1 but without wrapping the container creation in a method.



The two primary conclusions that I came to during this exercise are:

Make sure that you understand the API and code that you are calling.  It may not always be black and white.  As in example #2 above, forgetting that this is a delegate can lead to the wrong behavior.
Don’t rely blindly on example code from the internet.  Some of the code that I have posted is probably error prone.  Sample code is just that: a sample.
沙发
发表于 2015-10-2 02:42:47 | 只看该作者
感激涕零,谢谢楼主的好贴













当红小生
莫忘归途之绝对天师
上海红双喜香烟价格
最新娱乐新闻
誓不为妻:全球豪娶少夫人
金华新闻
丽水新闻播报
红三环香烟
茂大雪茄价格表图
八卦新闻
浙江新闻网女性频道
星座运势
最新国际形式
浙江教育发展
冬虫夏草香烟
凤凰子二号
欧美风
杭州新闻
一周热闻
剑凌太虚
板凳
发表于 2015-10-4 22:55:22 | 只看该作者
地板
发表于 2015-10-5 12:20:13 | 只看该作者

926

主题

1493

帖子

4128

积分

星星组

积分
4128
5#
发表于 2016-2-23 16:13:34 | 只看该作者
不太了解这个的,觉得不错












沈阳DLB医院
冬昆明DLB医院
昆明DL医院
广州DLB医院
哈尔滨治疗DLB医院
沈阳DL医院
黑龙江DLB医院
哈尔滨DLB医院
哈尔滨DL医院
治疗DLB专科医院
沈阳SEO

926

主题

1493

帖子

4128

积分

星星组

积分
4128
6#
发表于 2016-3-19 12:52:34 | 只看该作者
牛啊,想不到的强帖












沈阳DLB医院
冬昆明DLB医院
昆明DL医院
广州DLB医院
哈尔滨治疗DLB医院
沈阳DL医院
黑龙江DLB医院
哈尔滨DLB医院
哈尔滨DL医院
治疗DLB专科医院
沈阳SEO
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表