我为我的 WPF 应用程序编写了一个简单的中介(它是此处找到的代码的派生)。
public class Messenger
{
private IDictionary<Type, IList<MessageObserver>> observers;
public Messenger()
{
observers = new Dictionary<Type, IList<MessageObserver>>();
}
public IDisposeObserver AddObserver<TMessageType>(Action<TMessageType> handler)
where TMessageType : Message { }
protected abstract void RemoveObserver<TMessageType>(Action<TMessageType> handler)
where TMessageType : Message { }
public abstract void PostMessage<TMessageType>(TMessageType message)
where TMessageType : Message { }
}
Message
只是一个空类,它为通过Messenger
. 这个想法是您将从此类派生以创建具有相关数据的特定消息类(有点像EventArgs
)。
我的实现不同的地方在于我想删除观察者的方式。我希望能够指定何时应以声明性方式删除它们,如下所示:
MessengerInstance.AddObserver<LoginMessage>(HandleLogin)
.RemoveObserverWhen(message => message.LoginResult == LoginResult.Successful);
该RemoveObserverWhen
方法需要一个Predicate<T>
whereT
应该是AddObserver
方法中指定的消息类型。
这里的想法是您可以在注册观察者本身的同一位置指定删除观察者的逻辑。然后,Messenger 类将在消息处理程序运行后检查谓词,如果谓词评估为真,则删除消息处理程序和删除处理程序。
每个消息处理程序都可以有任意数量的删除处理程序,因此我将其打包在一个名为MessageObserver
.
public class MessageObserver : IDisposeObserver
{
private IList<object> disposalHandlers;
public MessageObserver(object observer)
{
Observer = observer;
disposalHandlers = new List<object>();
}
public object Observer { get; private set; }
public IList<object> DisposalHandlers
{
get { return disposalHandlers; }
}
public IDisposeObserver RemoveObserverWhen<T>(Predicate<T> predicate)
where T : Message
{
disposalHandlers.Add(predicate);
return this;
}
}
提供方法的MessageObserver
工具。IDisposeObserver
RemoveObserverWhen
public interface IDisposeObserver
{
IDisposeObserver RemoveObserverWhen<T>(Predicate<T> predicate)
where T : Message;
}
这里的想法是IDisposeObserver
可以返回一个实例,以便可以链接方法。
所有这些都有效,我的 viewModel 中有以下代码:
MessengerInstance.AddObserver<LoginMessage>(HandleLogin)
.RemoveObserverWhen<LoginMessage>(message => message.LoginResult == LoginResult.Successful)
.RemoveObserverWhen<LoginMessage>(SecondDisposalHandler);
我遇到的问题是,仅当我LoginMessage
在调用RemoveObserver
方法时指定泛型参数(在这种情况下)时才有效。我希望能够以文章开头描述的方式调用这些方法。
我认为我需要以某种方式返回一个泛型IDisposeObserver
,但如果我进行此更改,则MessageObserver
必须将其设为泛型,然后我无法指定约束,因为Messenger
该类是非泛型的。
所以我的问题是,我的代码是否可以更新,以便在调用RemoveObserverWhen
方法时不必指定消息类型,还是必须接受当前的解决方案?
注意:我知道还有其他可用的实现,但我这样做是为了帮助我理解 C# 中的面向对象设计原则和泛型,所以请不要向我指出其他实现的方向。