kerryjiang / SuperSocket

SuperSocket is a light weight, cross platform and extensible socket server application framework.
Apache License 2.0
3.95k stars 1.15k forks source link

自定 AppSession 时 无法直接调用 SendAsync() #523

Open Songxt opened 3 years ago

Songxt commented 3 years ago

public class MySession : AppSession { private readonly ILogger _logger;

    public MySession(ILogger<MySession> logger)
    {
        _logger = logger;
    }

    public ValueTask SendAsync(ReadOnlyMemory<byte> data)
    {
        _logger.LogInformation($"AppSever Send :{BitConverter.ToString(data.ToArray()).Replace("-"," ")}");
        return ((IAppSession)this).SendAsync(data);
    }
}

无法直接使用基类的SendAsync,只能通过转化IAppSession使用

chucklu commented 3 years ago

That's the way how Explicit Interface Implementation works. You can try the solution from Why can't I call methods within a class that explicitly implements an interface?


//To avoid a lot of boring casts on your class, you could create a pointer as the interface type

public class Foo : IBar
{
    readonly IBar bar;
    public Foo()
    {
       bar = this;
    }
}

//And then call members using bar.
Songxt commented 3 years ago

That's the way how Explicit Interface Implementation works. You can try the solution from Why can't I call methods within a class that explicitly implements an interface?

//To avoid a lot of boring casts on your class, you could create a pointer as the interface type

public class Foo : IBar
{
    readonly IBar bar;
    public Foo()
    {
       bar = this;
    }
}

//And then call members using bar.

That's the way how Explicit Interface Implementation works. You can try the solution from Why can't I call methods within a class that explicitly implements an interface?

//To avoid a lot of boring casts on your class, you could create a pointer as the interface type

public class Foo : IBar
{
    readonly IBar bar;
    public Foo()
    {
       bar = this;
    }
}

//And then call members using bar.

谢谢,但是我觉得直接开放使用 virtual 来使用 更好

chucklu commented 3 years ago

Here is a discussion on stackoverflow C# Interfaces. Implicit implementation versus Explicit implementation

Songxt commented 3 years ago

Here is a discussion on stackoverflow C# Interfaces. Implicit implementation versus Explicit implementation

Implicit implementation VS Explicit implementation, 我理解你的意思,AppSession 引用了多个接口,例如ILogFactory,IAppsession。但对于使用者来说,我不需要关注他底层是如何运行的,否则会很迷惑。继承AppSession的派生类为什么无法直接使用SendAsync,理应开放由 IAppSession 继承的基础方法。

kerryjiang commented 3 years ago

很多情况下是发送协议已经封装好了的,Send的时候只需传入包实例就行了,直接开放二进制数据的发送接口可能会不太妥当,这是我的考量。

Songxt commented 3 years ago

namespace MSocketCore.MSocket { [MyCmdFilter] [Command(Key = "01")] public class AFN01: IAsyncCommand<MySession,MyPackage> { private readonly ILogger _logger;

    public AFN01(ILogger<AFN01> logger)
    {
        _logger = logger;
    }

    private readonly MessageClient _client;

    public AFN01(MessageClient client)
    {
        _client = client;
    }

    public ValueTask ExecuteAsync(MySession session, MyPackage info)
    {
        _logger.LogInformation($"App Recevice:{info.Sn}[Confirm]\n{info.Message}");

        _client.SendMessage("aa", "ddd");
        var name = UserDAL.GetUserIdBySn(info.Sn);
        switch (info._Fn)
        {
            case 1:
                _client.SendMessage(name, info.Sn + "操作成功" + "\n");
                break;
            case 2:
                _client.SendMessage(name, info.Sn + "操作失败" + "\n");
                break;
        }

        return new ValueTask();
    }
}

}

上述代码 IAsyncCommand<MySession,MyPackage> 类似这种自定的session 就无法直接使用。当然默认的IAPPSession可以使用,但发送同样存在直接发送字节和package的情况,但是继承了Appsession反而无法使用了