Prism - EventAggregator.GetEvent<> .Subscribe() - 使用泛型&约束上 [英] Prism - EventAggregator.GetEvent<>.Subscribe() - Using Generics & Contraints

查看:359
本文介绍了Prism - EventAggregator.GetEvent<> .Subscribe() - 使用泛型&约束上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



如果我使用诸如

的某些东西b
$ b

  eventAggregator.GetEvent< string>()。订阅(MyMethod)

然后它一切正常,当事件被发布时,我的方法被触发。



然而,当移动到更复杂除了I字符串以外的对象我遇到了问题。



我有一堆类都来自接口(IRequest),例如

我有我的事件类设置如下

  public class MyEvent< TRequest> :PubSubEvent< MyClass< TRequest>> TRequest:IRequest {} 

我有一个泛型类(MyClass),它使用IRequest的对象现在,让我说我发布了一个MyClass的事件,它使用了它内部的对象Profile:



  eventAggregator.GetEvent< MyEvent< Profile>>()。Publish(myProfileObject); 

在我的订阅中,我想要一个可以捕获MyEvent的所有事件的方法 - 不管T是否为配置文件或从IRequest派生的其他对象 - 这是我似乎有问题的地方。



在下面的例子中,第一个作品,但第二个没有 - 我最好喜欢使用与第二种类似的东西。

  eventAggregator.GetEvent< MyEvent< Profile>>()。订阅(TEST1); 
void test1(MyClass< Profile> obj)
{
// Some some here
}

eventAggregator.GetEvent< MyEvent< IRequest>> ().Subscribe(TEST2);
void test2< T>(MyClass< T> obj)其中T:IRequest
{
//永远不会被调用
}

我的假设是,因为配置文件派生自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>其中T:IRequest {} 

public class MyClass< T> :IMyClass< T>其中T:IRequest {}

public class MyEvent< TValue> :PubSubEvent< IMyClass< TValue>> TValue:IRequest {}

然后你的事件聚合器看起来像这样:

  _eventAggregator.GetEvent< MyEvent< IRequest>>()。Subscribe(Received); 

private void Received(IMyClass< IRequest> obj)
{

}

_eventAggregator.GetEvent< MyEvent< IRequest>> ().Publish(new MyClass< Profile>());

这有帮助吗?


I am having an issue subscribing to events with the event Aggregator that comes as part of the prism framework.

If I use something such as

eventAggregator.GetEvent<string>().Subscribe(MyMethod)

then it all works ok, my method fires when an event has been published.

However, when moving to a more complex object other than I string I run into problems.

I have a bunch of classes that all derive from an Interface (IRequest) for example

I have my event class setup as follows

public class MyEvent<TRequest> : PubSubEvent<MyClass<TRequest>> where TRequest : IRequest {}

I have a generic class (MyClass) that uses an object of IRequest inside it - again, all seems to work ok at this point.

Now, lets say I publish an event of MyClass that uses the object Profile inside it:

eventAggregator.GetEvent<MyEvent<Profile>>().Publish(myProfileObject);

In my subscription I would like a method that can catch all events of MyEvent - Irrelevant of whether T is Profile or some other object that derives from IRequest - this is where I seem to be having problems.

In the following examples, the first works, but the second doesn't - I would ideally like to use something similar to the second.

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
}

My assumption is that because Profile derives from IRequest then it should work??? But it doesn't!!

Any help would be appreciated.

UPDATE
If I use the following, it does work, but would require me to create a separate subscription for each type of IRequest available - I'm looking to only have the one subscription.

eventAggregator.GetEvent<MyEvent<Profile>>().Subscribe(test2);
eventAggregator.GetEvent<MyEvent<User>>().Subscribe(test2);

解决方案

MyEvent<IRequest> and MyEvent<Profile> are not the same, so the EventAggregator doesn't see this as the same event. To allow for covariant types, you can fix it with the out modifier in C# 4. Something like this should work:

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 { }

Then your event aggregator would look something like:

 _eventAggregator.GetEvent<MyEvent<IRequest>>().Subscribe(Received);

 private void Received(IMyClass<IRequest> obj)
 {

 }

_eventAggregator.GetEvent<MyEvent<IRequest>>().Publish(new MyClass<Profile>());

Does this help?

这篇关于Prism - EventAggregator.GetEvent&lt;&gt; .Subscribe() - 使用泛型&amp;约束上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆