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

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操作方法。但是您的操作方法代码不会等待该方法被触发,因此,在触发DashboardService事件时,OnConnected永远不可能存在。

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


这意味着实例将与所有注入实例的请求共享。但这也意味着在创建请求甚至监听之前,实例可能正在更改状态。否则该事件可能会在请求之间触发。



因此,由于在创建DashboardAdapter时不询问DashboardService的当前状态,因此_isConnected可能是错误的。

在操作方法中创建的DashboardAdapter

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,即使没有收到请求,它也会每10秒更改其isConnected状态。发出请求后,它将等待被通知已连接,然后输出。请注意,这是v4应用程序,但很容易适应v3



通过聊天讨论:

没有事件处理程序:

Chat Discussion History

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

DashboardAdapter使用IsConnected属性。

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/

10-10 04:23