Prism - EventAggregator.GetEvent<>.Subscribe() - 使用泛型和约束
Prism - EventAggregator.GetEvent<>.Subscribe() - Using Generics & Contraints
我在使用作为 prism 框架一部分的事件聚合器订阅事件时遇到问题。
如果我使用诸如
之类的东西
eventAggregator.GetEvent<string>().Subscribe(MyMethod)
那么一切正常,我的方法会在事件发布后触发。
然而,当移动到比我更复杂的对象时,我 运行 会遇到问题。
例如,我有一堆 class 都是从接口 (IRequest) 派生的
我的活动class设置如下
public class MyEvent<TRequest> : PubSubEvent<MyClass<TRequest>> where TRequest : IRequest {}
我有一个通用的 class (MyClass),它在其中使用了一个 IRequest 对象 - 同样,此时一切似乎都正常。
现在,假设我发布了一个使用其中的对象 Profile 的 MyClass 事件:
eventAggregator.GetEvent<MyEvent<Profile>>().Publish(myProfileObject);
在我的订阅中,我想要一个可以捕获 MyEvent 的所有事件的方法——与 T 是 Profile 还是派生自 IRequest 的某个其他对象无关——这是我似乎遇到问题的地方。
在下面的示例中,第一个有效,但第二个无效 - 我希望使用与第二个类似的东西。
eventAggregator.GetEvent<MyEvent<Profile>>().Subscribe(test1);
void test1 (MyClass<Profile> obj)
{
//Some stuff here
}
eventAggregator.GetEvent<MyEvent<IRequest>>().Subscribe(test2);
void test2<T>(MyClass<T> obj) where T : IRequest
{
//never gets called
}
我的假设是因为 Profile 派生自 IRequest 那么它应该可以工作???但事实并非如此!!
如有任何帮助,我们将不胜感激。
更新
如果我使用以下内容,它确实有效,但需要我为每种可用的 IRequest 类型创建一个单独的订阅 - 我希望只有一个订阅。
eventAggregator.GetEvent<MyEvent<Profile>>().Subscribe(test2);
eventAggregator.GetEvent<MyEvent<User>>().Subscribe(test2);
MyEvent<IRequest>
和 MyEvent<Profile>
不同,因此 EventAggregator 不会将此视为同一事件。为了允许协变类型,您可以使用 C# 4 中的 out 修饰符来修复它。像这样的东西应该可以工作:
public interface IMyClass<out T> where T : IRequest { }
public class MyClass<T> : IMyClass<T> where T : IRequest { }
public class MyEvent<TValue> : PubSubEvent<IMyClass<TValue>> where TValue : IRequest { }
那么您的事件聚合器将类似于:
_eventAggregator.GetEvent<MyEvent<IRequest>>().Subscribe(Received);
private void Received(IMyClass<IRequest> obj)
{
}
_eventAggregator.GetEvent<MyEvent<IRequest>>().Publish(new MyClass<Profile>());
这有帮助吗?
我在使用作为 prism 框架一部分的事件聚合器订阅事件时遇到问题。
如果我使用诸如
之类的东西eventAggregator.GetEvent<string>().Subscribe(MyMethod)
那么一切正常,我的方法会在事件发布后触发。
然而,当移动到比我更复杂的对象时,我 运行 会遇到问题。
例如,我有一堆 class 都是从接口 (IRequest) 派生的
我的活动class设置如下
public class MyEvent<TRequest> : PubSubEvent<MyClass<TRequest>> where TRequest : IRequest {}
我有一个通用的 class (MyClass),它在其中使用了一个 IRequest 对象 - 同样,此时一切似乎都正常。
现在,假设我发布了一个使用其中的对象 Profile 的 MyClass 事件:
eventAggregator.GetEvent<MyEvent<Profile>>().Publish(myProfileObject);
在我的订阅中,我想要一个可以捕获 MyEvent 的所有事件的方法——与 T 是 Profile 还是派生自 IRequest 的某个其他对象无关——这是我似乎遇到问题的地方。
在下面的示例中,第一个有效,但第二个无效 - 我希望使用与第二个类似的东西。
eventAggregator.GetEvent<MyEvent<Profile>>().Subscribe(test1);
void test1 (MyClass<Profile> obj)
{
//Some stuff here
}
eventAggregator.GetEvent<MyEvent<IRequest>>().Subscribe(test2);
void test2<T>(MyClass<T> obj) where T : IRequest
{
//never gets called
}
我的假设是因为 Profile 派生自 IRequest 那么它应该可以工作???但事实并非如此!!
如有任何帮助,我们将不胜感激。
更新
如果我使用以下内容,它确实有效,但需要我为每种可用的 IRequest 类型创建一个单独的订阅 - 我希望只有一个订阅。
eventAggregator.GetEvent<MyEvent<Profile>>().Subscribe(test2);
eventAggregator.GetEvent<MyEvent<User>>().Subscribe(test2);
MyEvent<IRequest>
和 MyEvent<Profile>
不同,因此 EventAggregator 不会将此视为同一事件。为了允许协变类型,您可以使用 C# 4 中的 out 修饰符来修复它。像这样的东西应该可以工作:
public interface IMyClass<out T> where T : IRequest { }
public class MyClass<T> : IMyClass<T> where T : IRequest { }
public class MyEvent<TValue> : PubSubEvent<IMyClass<TValue>> where TValue : IRequest { }
那么您的事件聚合器将类似于:
_eventAggregator.GetEvent<MyEvent<IRequest>>().Subscribe(Received);
private void Received(IMyClass<IRequest> obj)
{
}
_eventAggregator.GetEvent<MyEvent<IRequest>>().Publish(new MyClass<Profile>());
这有帮助吗?