如何将现有的代理添加到事件中?

huangapple go评论65阅读模式
英文:

How can I add an existing delegate to an event?

问题

我要翻译的内容如下:

"I have an object that has events. I want to reset that object to default but keep the existing event subscriptions. My aim is to have a bunch of subscriptions to events on this object (_myRepo), then at some point I want to set _myRepo = null, create a new copy of the object with its default state and then add back all the previously saved subscribers. I use a generic approach instead of strong typing due to there being many repos in this class.

The issue I'm having is trying to add the subscription back to the event once it's has been recreated. I'm trying to do this in the ApplyCachedEventHandlers() function. How do I add this delegate back to the new object's event?

This is what I'm doing so far...

private IMyRepo _myRepo;
private Dictionary<Type, Delegate> _subscribers = new Dictionary<Type, Delegate>();

public IMyRepo MyRepo
{
get
{
if (_myRepo == null)
_myRepo = new MyRepo(_transaction);
ApplyCachedEventHandlers(_myRepo);

    return _myRepo;
}

}

private void ResetRepo()
{
CacheEventHandlers(_myRepo);
_myRepo = null;
}

private void CacheEventHandlers(T repo)
{
if (repo == null)
return;

Type t = repo.GetType();
FieldInfo[] fia = t.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);

foreach (FieldInfo fi in fia)
{
    Delegate d = fi.GetValue(repo) as Delegate;
    if (d != null)
    {
        foreach (Delegate subscriber in d.GetInvocationList())
            _subscribers.Add(t, subscriber);
    }
}

}

private void ApplyCachedEventHandlers(T repo)
{
if (repo == null || _subscribers == null || _subscribers.Count < 1)
return;

Type t = repo.GetType();
FieldInfo[] fia = t.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);

foreach (KeyValuePair<Type, Delegate> subscriber in _subscribers)
{
    if (t == subscriber.Key)
    {
        foreach (FieldInfo fi in fia)
        {
            // This is where I get hung up
            Debug.WriteLine("Add the saved delegate to the subscriptions of the event (fi).");
        }
    }
}

}"

希望这对你有所帮助。

英文:

I have an object that has events. I want to reset that object to default but keep the existing event subscriptions. My aim is to have a bunch of subscriptions to events on this object (_myRepo), then at some point I want to set _myRepo = null, create a new copy of the object with it's default state and then add back all the previously save subscribers. I use a generic approach instead of strong typing due to their being many repos in this class.

The issue I'm having is trying to add the subscription back to the event once it's has been recreated. I'm trying to do this in the ApplyCachedEventHandlers() function. How do I add this delegate back to the new object's event?

This is what I'm doing so far...

private IMyRepo _myRepo;
private Dictionary&lt;Type, Delegate&gt; _subscribers = new Dictionary&lt;Type, Delegate&gt;();

public IMyRepo MyRepo
{
	get
	{
		if (_myRepo == null)
			_myRepo = new MyRepo(_transaction);
		ApplyCachedEventHandlers(_myRepo);

		return _myRepo;
	}
}

private void ResetRepo()
{
	CacheEventHandlers(_myRepo);
	_myRepo = null;
}

private void CacheEventHandlers&lt;T&gt;(T repo)
{
	if (repo == null)
		return;

	Type t = repo.GetType();
	FieldInfo[] fia = t.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);

	foreach (FieldInfo fi in fia)
	{
		Delegate d = fi.GetValue(repo) as Delegate;
		if (d != null)
		{
			foreach (Delegate subscriber in d.GetInvocationList())
				_subscribers.Add(t, subscriber);
		}
	}
}

private void ApplyCachedEventHandlers&lt;T&gt;(T repo)
{
	if (repo == null || _subscribers == null || _subscribers.Count &lt; 1)
		return;

	Type t = repo.GetType();
	FieldInfo[] fia = t.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);

	foreach (KeyValuePair&lt;Type, Delegate&gt; subscriber in _subscribers)
	{
		if (t == subscriber.Key)
		{
			foreach (FieldInfo fi in fia)
			{
				// This is where I get hung up
				Debug.WriteLine(&quot;Add the saved delegate to the subscriptions of the event (fi).&quot;);
			}
		}
	}
}

答案1

得分: 0

如果您想通过反射订阅事件,您不应该使用字段,而应该使用事件:

var eventInfos = type.GetEvents(); // 根据需要传递标志
foreach (KeyValuePair&lt;Type, Delegate&gt; subscriber in _subscribers)
{
    if (t == subscriber.Key)
    {
        foreach (EventInfo ei in eventInfos)
        {
            ei.AddEventHandler(repo, subscriber.Value); 
        }
    }
}
英文:

If you want to subscribe to event via reflection you should not work with fields, but with events:

var eventInfos = type.GetEvents(); // pass the flags if needed
foreach (KeyValuePair&lt;Type, Delegate&gt; subscriber in _subscribers)
{
    if (t == subscriber.Key)
    {
        foreach (EventInfo ei in eventInfos)
        {
            ei.AddEventHandler(repo, subscriber.Value); 
        }
    }
}

huangapple
  • 本文由 发表于 2023年5月18日 02:29:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76275196.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定