与Akka.Net演员的继承

时间:2017-02-15 08:17:41

标签: c# akka akka.net

我想知道如何使用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发送给父母演员的工作吗?

1 个答案:

答案 0 :(得分:0)

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

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