Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于Xrpc的XRPCServer.EventToken设计解耦的问题 #24

Open
snikeguo opened this issue Aug 23, 2020 · 6 comments
Open

关于Xrpc的XRPCServer.EventToken设计解耦的问题 #24

snikeguo opened this issue Aug 23, 2020 · 6 comments

Comments

@snikeguo
Copy link

snikeguo commented Aug 23, 2020

现有的是通过唯一的静态属性XRPCServer.EventToken 去获取当前的连接信息的。不够优雅~~
我有个思路,你看下:

using System;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    interface IMyInterFace
    {
        Task HelloWorld(string s);
    }

    //服务端这么设计:
    //MyInterFaceImpl继承IMyInterFace和“当前连接会话”的类(XRPCEventToken)
    //这个MyInterFaceImpl具体的对象也是你Xrpc底层反射创建的,创建好后,先转成XRPCEventToken 赋值好当前的“链接信息”等信息
    //最后调用MyInterFaceImpl实例的HelloWorld方法
    //这样解决了XRPCServer.EventToken的静态属性的问题。
    class MyInterFaceImpl :  XRPCEventToken,IMyInterFace
    {
        public Task HelloWorld(string s)
        {
            var 当前的Session = this.Session;//这个字段来自XRPCEventToken
            var 当前的Server = this.Server;
            var 当前的Request = this.Request;
            //...业务操作。
            return Task.CompletedTask;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

@snikeguo
Copy link
Author

snikeguo commented Aug 23, 2020

我的简单实现。已经测试可以用

using System;
using System.Reflection;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    
    interface IMyInterFace
    {
        Task HelloWorld(string s);
    }
    class MyInterFaceImpl : ServerInfo,IMyInterFace
    {
        public Task HelloWorld(string s)
        {
            Console.WriteLine($"Hello World!{s}");
            return Task.CompletedTask;
        }
    }
    class ServerInfo
    {
        public string Ipv4 { get; set; } = "127.0.0.1";
    }
    class Program
    {
        static void Main(string[] args)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();

            var v = assembly.GetTypes();

            //假设到这里 已经知道了要创建那个类型的对象了,

            Type MyInterFaceImplType = assembly.GetType("ConsoleApp1.MyInterFaceImpl");//获取要创建对象的类型

            Object MyInterFaceImplInstance = assembly.CreateInstance(MyInterFaceImplType.FullName);//创建对象

            ((ServerInfo)(MyInterFaceImplInstance)).Ipv4 = "666";//这里把链接信息赋给创建好的对象
            var needcallmi = MyInterFaceImplType.GetMethod("HelloWorld");//获取需要调用的mathodInfo
            needcallmi.Invoke(MyInterFaceImplInstance, new object[] { "123" });//call
        }
    }
}

@snikeguo
Copy link
Author

image

@beetlex-io
Copy link
Owner

这个主要看控制器的实例模式吧,如果每次调用都实例化这种设计是可行,如果是单实例则不好用了。

@snikeguo
Copy link
Author

单实例的话,就不用创建对象了,找到最前面第一次创建的对象,更新当前的连接信息即可。
顺便说一句,用户如果继承连接信息类的话,就赋值当前连接信息操作,如果用户没继承连接信息类,只是继承了IMyInterface(底层实现强转成父类,肯定是null),就不操作,说明用户不需要连接信息。

@beetlex-io
Copy link
Owner

单实例是所有用户共享实例,无法直接更新,这样会存在线程安全问题。

@snikeguo
Copy link
Author

那就单例模式下不允许这么做。实例模式下才允许

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants