我有以下服务依赖于另一个具有事件的类。
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/