首页新闻找找看学习计划

关于服务定位器的弱类型实现!

0
悬赏园豆:50 [已关闭问题] 关闭于 2013-02-08 22:13

  昨天提了这个问题,没人回答,看的人也不多,今天重新提问一下,希望可以有人帮我解决下这个问题。

  下面这段代码是服务定位器的强类型实现。  

  /// <summary>
    /// 服务接口
    /// </summary>
    public interface IMessageService
    {
        void SendMessage();
    }
    /// <summary>
    /// 继承服务接口的  EmailService 服务
    /// </summary>
    public class EmailService : IMessageService
    {
        public void SendMessage()
        {
            throw new NotImplementedException();
        }
    }
    /// <summary>
    /// 获取 相关服务的服务定位器 接口
    /// </summary>
    public interface IServiceLocator {
        IMessageService GetMessageService();
    }
    /// <summary>
    /// 获取 EmailService的 服务定位器类,继承IServiceLocator
    /// </summary>
    public class IEmailLocator : IServiceLocator
    {
        public IMessageService GetMessageService()
        {
            return new EmailService();
        }
    }
    /// <summary>
    /// 通知系统 类,用来调用相关服务类的SendMessage方法 发送信息
    /// </summary>
    public class NoticeSystem {
        /// <summary>
        /// 
        /// </summary>
        private IMessageService svc;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="locator"></param>
        public NoticeSystem(IServiceLocator locator)
        {
            svc = locator.GetMessageService();
        }
        /// <summary>
        /// 
        /// </summary>
        public void SendMessage()
        {
            svc.SendMessage();
        }
    }

  现在的问题是把IServiceLocator改为弱类型实现,书上只给出了下面的改变,具体的实现我怎么都搞不定(红色标出的是改动的地方,求高人帮助完善后面的实现):  

/// <summary>
    /// 获取 相关服务的服务定位器 接口
    /// </summary>
    public interface IServiceLocator
    {
        object GetService(Type serviceType);
        //IMessageService GetMessageService();
    }
    /// <summary>
    /// 通知系统 类,用来调用相关服务类的SendMessage方法 发送信息
    /// </summary>
    public class NoticeSystem {
        /// <summary>
        /// 
        /// </summary>
        private IMessageService svc;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="locator"></param>
        public NoticeSystem(IServiceLocator locator)
        {
            svc = (IMessageService)locator.GetService(typeof(IMessageService));
        }
        /// <summary>
        /// 
        /// </summary>
        public void SendMessage()
        {
            svc.SendMessage();
        }
    }

 

  

问题补充:

不知道是不是我说的不清楚,我再补充一下,下面这幅图,左边是服务接口和他的继承类,右边是服务定位器接口和他的继承类,结合上面的代码,现在要通过服务定位器EmailLocator得到EmailService,只需要在NoticeSystem实例化的时候,传入一个EmailLocator就OK了。同样要获取FaxService,传一个FaxLocator就行了。但问题是如果我又新添加了一种继承自IMessageService的服务呢?那我也得同时为IServiceLocator添加一个继承类来返回我添加的这个服务类型。这样是很麻烦的。而且,谁能肯定EmailLocator返回的一定是EmailService类型,FaxLocator返回的一定是FaxService类型呢?所以现在又回到上边那个问题了,应该可以有IServiceLocator的弱类型实现可以解决这两个问题,但书上就给了个这个,我实在不知道怎么完成后面的代码,最终实现我为IMessageService添加一个继承类,我的IServiceLocator就可以返回这个类的对象,就是这样!

小飞的DD的主页 小飞的DD | 初学一级 | 园豆:156
提问于:2013-02-07 08:45
< >
分享
所有回答(3)
0

不太明白你的饿意思,如果按照你那样写, 你把 那个实现部分改一下 不就行了 ,示例:

  public class IEmailLocator : IServiceLocator
    {
        //public IMessageService GetMessageService()
        //{
        //    return new EmailService();
        //}
        public object GetService(Type serviceType)
        {
            throw new NotImplementedException();
        }
    }
世界万物 | 园豆:276 (菜鸟二级) | 2013-02-07 09:16

怎么改才能返回我想要的继承IMessageService接口的XXXService类对象呢?请帮忙完成下,谢谢!

支持(0) 反对(0) 小飞的DD | 园豆:156 (初学一级) | 2013-02-07 09:21

@小飞的DD:  反射创建对象,既然你传参是serviceType ,直接创建类型就行,但是 你那个serviceType 必须实现接口IMessageService,

   public object GetService(Type serviceType)
        {
            object obj = Activator.CreateInstance(serviceType);
            return obj is IMessageService ? obj : null;
        }
         我觉得这里应该传 实现类型  svc = (IMessageService)locator.GetService(typeof(EmailService));           
支持(0) 反对(0) 世界万物 | 园豆:276 (菜鸟二级) | 2013-02-07 09:27

@随静而动: 照你这么来写的话,我的IMessageService接口又多加了一个FaxService的话,我要实现这个FaxService,还要去修改NoticeSystem类吗?这样反而不如 服务定位器的 强类型实现了啊!

支持(0) 反对(0) 小飞的DD | 园豆:156 (初学一级) | 2013-02-07 10:12

@小飞的DD:  明白你的意思了,就是如果新添加 一个 Service的话 你不想改动ServiceLocator 就可以让其发现你新创建的这个服务 是不? 那如果这样,不知道你还创建 serviceLocator 的接口干什么用啊? 抛开你说的弱引用,我觉得原来的就很好 ,不需要改动NotifySystem ,只需添加继承外围接口就可。

弱引用 实现求高手解答。

 
支持(0) 反对(0) 世界万物 | 园豆:276 (菜鸟二级) | 2013-02-07 11:17
0

有点不明白为什么书上会那么写? 弱引用是指 即使在对象有引用的情况下,也可能会被回收。

1. 那个对象要成为弱引用,看上去 好像是IMessageService ,但是这个对象是被 IServiceLocator 创建,觉得IServiceLocator 不用改。

2. NoticeSystem 使用到了IMessageService,可以在这个类里使用。参考如下:

 

  public class NoticeSystem
    {
        private readonly IMessageService _svc;
        private readonly WeakReference _weakReference;
        private readonly Type _Type;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="locator"></param>
        public NoticeSystem(IServiceLocator locator, bool keepReferenceAlive)
        {
            if (keepReferenceAlive)
                _svc = locator.GetMessageService();
            else
            {
                var svc = locator.GetMessageService();
                _weakReference = new WeakReference(svc);
                _Type = svc.GetType();
            }
        }

        public IMessageService Target
        {
            get
            {
                IMessageService svc = _svc;

                if (svc == null)
                {
                    if (_weakReference != null)
                    {
                        object target = _weakReference.Target;

                        if (target == null)
                            target = Activator.CreateInstance(_Type);
                        if (target != null)
                            svc = (IMessageService)target;
                    }
                }

                return svc;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public void SendMessage()
        {
            Target.SendMessage();
        }
    }
Qlin | 园豆:2403 (老鸟四级) | 2013-02-07 09:55
0

class ServiceLocator : IServiceLocator
    {
        private IDictionary<object, object> services;
        internal ServiceLocator()
        {
            services = new Dictionary<object, object>();
            this.services.Add(typeof(IMessageService), new EmailService());
        }
        public object GetService(Type type)
        {
           return services[type];
        }
    }

 

 public NoticeSystem(IServiceLocator locator)
        {
            svc = (IMessageService)locator.GetService(typeof(IMessageService));
        }

Yu | 园豆:12944 (专家六级) | 2013-02-07 14:00
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册