c# - ServiceStack:依赖调用

标签 c# servicestack

我有以下服务,它依赖于另一个有事件的类。

public class DashboardService : SecureService
{
    private readonly DashboardAdapter _dashboardAdapter;
    private bool _isConnected;

    public DashboardService(DashboardAdapter dashboardAdapter)
    {
        _dashboardAdapter = dashboardAdapter;
        _dashboardAdapter.OnConnection += OnConnection;
    }

    public object Get(DashboardRequest request)
    {
        return new Dashboard { IsConnected = _isConnected };
    }

    private void OnConnection(object sender, ConnectionEventArgs e)
    {
        _isConnected = e.IsConnected;
    }
}

问题是,事件永远不会触发,就像我执行以下操作一样,事件会触发并适本地设置我的属性:

    public object Get(DashboardRequest request)
    {
        var dashboard = new DashboardAdapter();
        dashboard.OnConnected += OnConnection;
        return new Dashboard { IsConnected = _isConnected };
    }

我已经像这样在容器中注册了我的适配器:

var dashboard = new DashboardAdapter();
container.Register(dashboard);

我是否遗漏了什么或以错误的方式解决了这个问题?

最佳答案

不幸的是,你所拥有的不太可能工作,因为你有很多竞争条件。

# DashboardService存在的时间不够长:

当您向 DashboardRequest 发出请求时路由 DashboardService 的新实例是为处理该请求而创建的。

这将设置 OnConnection方法与您的依赖关系,ServiceStack 将调用您的 Get Action 方法。但是您的操作方法代码不会等待该方法被触发,因此 DashboardServiceOnConnected 时永远不可能存在事件被触发。

public object Get(DashboardRequest request)
{
    // Should have waited here for the event to be triggered
    while(!_connected)
        System.Threading.Thread.Sleep(100);
    
    return new Dashboard { IsConnected = _isConnected };
}

#事件发生在请求之前或之后 您已经创建了 DashboardAdapter 的单个实例已在容器中注册。

var dashboard = new DashboardAdapter();
container.Register(dashboard);

这意味着该实例将与注入(inject)它的所有请求共享。但这也意味着实例可能会在创建请求之前改变状态,甚至会监听它。或者事件可以尝试在请求之间触发。

Race

因为您没有查询 DashboardAdapter 的当前状态当你创建 DashboardService然后 _isConnected可能是错误的。

# DashboardAdapter在 Action 方法中创建:

public object Get(DashboardRequest request)
{
    var dashboard = new DashboardAdapter();
    dashboard.OnConnected += OnConnection;
    return new Dashboard { IsConnected = _isConnected };
}

这里还有一个小的竞争条件,但它更有可能起作用,因为你的事件触发器更有可能与你的 DashboardService 的存在重叠。 .这相当于:

container.RegisterAutoWiredType(typeof(DashboardAdapter), ReuseScope.Request);

#示例:

This console app gist展示了一个非常粗略的等待事件被触发的例子。它创建了一个 DashboardAdapter这将改变它的 isConnected每 10 秒状态一次,即使没有收到请求。当发出请求时,它会等待被连接的通知,然后输出。 请注意,这是一个 v4 应用,但它很容易适应 v3


###来自聊天讨论:

#没有事件处理器:

Chat Discussion History

您可能不需要服务中的事件处理程序,因为单个 DashboardAdapter container 中的实例将继续更新它的状态,您可以在 DashboardService 的短暂生命周期内根据需要阅读此内容实例。

DashboardAdapter使用 IsConnected属性(property)。

public class DashboardAdapter
{
    readonly MyBrokerService service;
    public bool IsConnected { get; set; }

    public DashboardAdapter()
    {
        // Create your connection to the WCF broker service

        // Pseudo code for the connection, replace with your actual implementation
        service = new MyBrokerService();
        service.onConnectionStatusChanged += (sender, e) => {
            IsConnected = e.isConnected;
        };
    }
}

然后检查 DashboardService简直就是

public class DashboardService : SecureService
{
    private readonly DashboardAdapter _dashboardAdapter;

    public DashboardService(DashboardAdapter dashboardAdapter)
    {
        _dashboardAdapter = dashboardAdapter;
    }

    public object Get(DashboardRequest request)
    {
        return new Dashboard { IsConnected = _dashboardAdapter.IsConnected };
    }
}

关于c# - ServiceStack:依赖调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24135776/

相关文章:

C#类构造函数默认值问题

c# - WindowsIdentity.Impersonate() 混淆

c# - 使用 OnClick 事件与 asp :Button 的 PostBackUrl 属性

ServiceStack 路由和动词

c# - 推送 bin/js 文件后,Servicestack 丢失 session ,直到缓存清除

c# - Utf8Json根据标记字段反序列化为类型

c# - ASP FileUpload InputStream 和 System.IO.File.OpenRead

asp.net-mvc - 使用 MVC Controller 进行 ServiceStack 身份验证

servicestack - JsonServiceClient.Get 中 IReturn 和 IReturnVoid 的用途

servicestack - 如何覆盖 ServiceStack.Text 中的字符串序列化?