昨天提了这个问题,没人回答,看的人也不多,今天重新提问一下,希望可以有人帮我解决下这个问题。
下面这段代码是服务定位器的强类型实现。
/// <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就可以返回这个类的对象,就是这样!
不太明白你的饿意思,如果按照你那样写, 你把 那个实现部分改一下 不就行了 ,示例:
public class IEmailLocator : IServiceLocator { //public IMessageService GetMessageService() //{ // return new EmailService(); //} public object GetService(Type serviceType) { throw new NotImplementedException(); } }
怎么改才能返回我想要的继承IMessageService接口的XXXService类对象呢?请帮忙完成下,谢谢!
@小飞的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));
@随静而动: 照你这么来写的话,我的IMessageService接口又多加了一个FaxService的话,我要实现这个FaxService,还要去修改NoticeSystem类吗?这样反而不如 服务定位器的 强类型实现了啊!
@小飞的DD: 明白你的意思了,就是如果新添加 一个 Service的话 你不想改动ServiceLocator 就可以让其发现你新创建的这个服务 是不? 那如果这样,不知道你还创建 serviceLocator 的接口干什么用啊? 抛开你说的弱引用,我觉得原来的就很好 ,不需要改动NotifySystem ,只需添加继承外围接口就可。
弱引用 实现求高手解答。
有点不明白为什么书上会那么写? 弱引用是指 即使在对象有引用的情况下,也可能会被回收。
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(); } }
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));
}