编程语言
首页 > 编程语言> > c#-注册来自不同类的回调

c#-注册来自不同类的回调

作者:互联网

对于标准的请求服务器,我使用以下代码将请求与服务进行匹配并处理传入的请求.

服务提供者

public class ServiceProvider
{
    public ServiceProvider()
    {
        Services = new Dictionary<Type, IService>
        {
            { typeof(FooRequest), new FooService() },
            { typeof(BarRequest), new BarService() },
        };
    }

    protected void OnRequestReceived(object request)
    {
        Services[request.GetType()].Process(request);
    }
}

FooService

public class FooService : IService
{
    public object Process(object request)
    {
        // Process request
    }
}

这就像一种魅力,但我想摆脱每种服务的一种方法(流程).我尝试使用“动作和代表”进行操作,但以某种方式无法完成这种简单的结构.

基本上,我的问题是:如何在需要调用它们时注册另一个类的多个方法/回调并将其存储在字典中?

所需结果(伪代码):

服务提供者

public class ServiceProvider
{
    public ServiceProvider()
    {
        var fooService = new FooService();
        var barService = new BarService();

        Handlers = new Dictionary<Type, Action>
        {
            { typeof(FooRequestA), fooService.ProcessA },
            { typeof(FooRequestB), fooService.ProcessB },
            { typeof(BarRequest), barService.Process },
        };
    }

    protected void ProcessRequest(object request)
    {
        Handlers[request.GetType()].Invoke(request);
    }
}

FooService

public class FooService
{
    public object ProcessA(FooRequestA request)
    {
        // Process request A
    }

    public object ProcessB(FooRequestB request)
    {
        // Process request B
    }
}

解决方案的改进

使用以下方法,您可以简化重复的请求-服务匹配代码:

public void RegisterHandler<TRequest>(Action<TRequest> function)
{
    Handlers.Add(typeof(TRequest), request => function.Invoke((TRequest) request));
}

结果是非常干净的用法:

RegisterHandler<FooRequestA>(request => fooService.ProcessA(request));

解决方法:

这是我能想到的最好的. (同时尽量保持您的要求……可能会有更好的方法来实现您实际想要做的事情).我认为您使用该解决方案会失去一点类型安全性:

FooService

public class FooService
{
    public object ProcessA(FooRequestA request)
    {
        return null;
    }
    public object ProcessB(FooRequestB request)
    {
        return null;
    }
}

酒吧服务

public class BarService
{
    public void Process(BarRequest request)
    { }
}

服务提供者

public class ServiceProvider
{
    private readonly Dictionary<Type, Action<object>> Handlers;
    public ServiceProvider()
    {
        var fooService = new FooService();
        var barService = new BarService();

        Handlers = new Dictionary<Type, Action<object>>
        {
            {typeof(FooRequestA), request => fooService.ProcessA((FooRequestA)request)},
            {typeof(FooRequestB), request => fooService.ProcessB((FooRequestB)request)},
            {typeof(BarRequest), request => barService.Process((BarRequest)request)}
        };
    }

    protected void ProcessRequest(object request)
    {
        Handlers[request.GetType()].Invoke(request);
    }
}

由于您无法将方法组(例如fooService.ProcessA)转换为Action,因此您需要将lambda添加到Dictionary< Type,Action< object>并提供请求作为参数.

标签:delegates,func,action,c,net
来源: https://codeday.me/bug/20191119/2033052.html