继承 Akka.Net 个演员

Inheritance with Akka.Net actors

我想知道,如何用Akka.Net实现继承。我希望基本 actor 处理基本消息,让子 actor 处理子消息。

例如,我有以下层次结构:

public class BaseMessage
{
    public string Data { get; set; }
}

public class ChildMessage : BaseMessage
{
    public string ChildData { get ;set; }
}

public abstract class BaseActor : ReceiveActor
{
    private string baseData;

    public BaseActor()
    {
        Receive<BaseMessage>(m => {
            baseData = m.Data;
        });

        // be aware that adding ReceiveAny handler in base class means that you wont be able to add any handlers in descendant actors
        // just override Unhandled method
    }
}

public class MyActor : BaseActor 
{
    private string myData;    

    public MyActor()
    {
        Receive<ChildMessage>(m => {
        myData = m.ChildData;

        // obviously BaseActor won't receive BaseMessage
        // so I should somehow send BaseMessage to it

        // option 1, not sure will it work
        BaseMessage baseMessage = m as BaseMessage;
        Self.Tell(baseMessage);

        // option 2, definitely should work
        BaseMessage baseMessage = new BaseMessage { Data = m.Data };
        Self.Tell(baseMessage);
        });
    }
}

问题是:选项 1 向父 actor 发送消息是否有效?

不幸的是,它不会以这种方式工作,因为父 actor 会拦截 ChildMessage 发送给子 actor。所以,我的解决方案如下

public class BaseMessage
{
    public string Data { get; set; }
}

public class ChildMessage : BaseMessage
{
    public string ChildData { get ;set; }
}

public abstract class BaseActor : ReceiveActor
{
    private string baseData;

    public BaseActor()
    {
        Receive<BaseMessage>(m => {
            ProcessMessage(m);
        });

        // be aware that adding ReceiveAny handler in base class means that you wont be able to add any handlers in descendant actors
        // just override Unhandled method instead
    }

    protected virtual void ProcessMessage(BaseMessage m)
    {
        baseData = m.Data;
    }
}


public class MyActor: BaseActor
{
    private string myData;    

    public MyActor()
    {
        // no interceptor for ChildMessage here, because parent class has interceptor for BaseMessage and it will handle ChildMessage too
    }

    protected override void ProcessMessage(BaseMessage m)
    {
        base.ProcessMessage(m);

        // not qute OOP way, but it works
        var childMessage = m as ChildMessage;
        if(childMessage != null)
        {
            myData = childMessage.ChildData;
        }
    }
}