这是我的视图模型中的业务逻辑吗,是否允许这样做?
Is this business logic in my view model, and is it allowed?
我有一个必须始终运行的 WCF 服务,因此由 Windows 服务托管。我的 Windows 服务模型有简单的启动代码:
主机服务:
public void StartService()
{
if (_hostController.Status != ServiceControllerStatus.Stopped && _hostController.Status != ServiceControllerStatus.StopPending)
{
var msg = string.Format("Service '{0}' must be in status '{1}' or '{2}' to accept a 'Start' command.",
HostResources.ServiceName, ServiceControllerStatus.Stopped, ServiceControllerStatus.StopPending);
throw new HostServiceException(msg, HostServiceException.HostServiceExceptionCategory.ServiceStatusControl);
}
try
{
_hostController.Start();
}
catch (Exception ex)
{
if (ex is Win32Exception || ex is InvalidOperationException)
{
throw new HostServiceException(string.Format("'{0}' failed to respond properly to a 'StartService` command: '{1}'", _hostController.ServiceName, ex.Message), ex);
}
throw;
}
try
{
_hostController.WaitForStatus(ServiceControllerStatus.Running, _waitForStatusTimeout);
}
catch (TimeoutException tx)
{
throw new HostServiceException(string.Format("{0} did not start respond after {1} seconds and the 'Start' command timed out.", _hostController.ServiceName, _waitForStatusTimeout.TotalSeconds), tx);
}
if (ServiceControllerStatus.Running != _hostController.Status)
{
throw new HostServiceException(string.Format("The 'StartService' command for '{0}' failed. The Service has a status of '{1}'.", _hostController.ServiceName, _hostController.Status));
}
}
我的 WCF 服务有更简单的启动代码:
调度服务:
public void Start()
{
_isBusy = false;
var interval = _config.Settings.ServicePollingInterval * 1000;
_pollTimer = new Timer(interval);
_pollTimer.Enabled = true;
_pollTimer.Elapsed += PollTimerElapsed;
_pollTimer.Start();
Status = SchedulerServiceStatus.Running;
var msg = string.Format("'{0}' started with the timer set for {1} second{2} intervals.", SchedulerResources.ServiceName, _pollTimer.Interval / 1000, _pollTimer.Interval / 1000 > 1 ? "s" : "");
_logger.Info(msg);
StatusChanged(this, new SchedulerStatusChangeEventArgs(Status, msg));
}
这里是我的视图模型中的代码,因为只有它可以启动 Windows 服务,它才会启动 WCF 服务:
SchedulerViewModel:
private void ExecuteStart()
{
if (_hostModel.ServiceStatus != ServiceControllerStatus.Running)
{
_logger.Warn("The '" + _hostModel.ServiceName + "' host service is not running. The '" + GetType().Name + "' will attempt to start it.");
try
{
_hostModel.StartService();
}
catch (Exception ex)
{
var msg = string.Format("The '{0}' could not start the '{1}' host service: {2}", GetType().Name, _hostModel.ServiceName, ex.Message);
_logger.Error(msg, ex);
throw new HostServiceException(msg, HostServiceException.HostServiceExceptionCategory.ServiceController, ex);
}
}
try
{
_scheduler.Start();
}
catch (Exception ex)
{
throw new SchedulerServiceException(ex.Message, SchedulerServiceException.SchedulerServiceExceptionCategory.SchedulerControl, ex);
}
SchedulerStatus = _scheduler.Status;
CommandsCanExecuteChanged();
}
这确实不是视图逻辑,但也算不上业务逻辑;更像是家政服务:我只能在水源打开的情况下使用洗衣机。现在我真的不认为需要一个只有 HostModel
和 SchedulerService
实例的全新模型,只是为了这个决定。评审团对我当前的设置有何看法?
我会将所有代码推送到另一个服务后面,并通过接口将其注入到 VM 中,我这样做是因为我假设 WCF 通过事件公开状态并且您想在 UI.如果您将此推到另一个服务后面,则允许 'shape' 公开状态进入更 UI 适合在 VM 中使用的中心模型。
如果你这样做,从 VM 的角度来看,它所知道的只是 'start\stop' 方法和一个事件处理程序 - 然后实现被抽象出来,并通过模拟非常容易地测试 VM .
为了更进一步,我会考虑使用 Reactive 扩展而不是 CLR 事件来传达服务中的状态变化。
我有一个必须始终运行的 WCF 服务,因此由 Windows 服务托管。我的 Windows 服务模型有简单的启动代码:
主机服务:
public void StartService()
{
if (_hostController.Status != ServiceControllerStatus.Stopped && _hostController.Status != ServiceControllerStatus.StopPending)
{
var msg = string.Format("Service '{0}' must be in status '{1}' or '{2}' to accept a 'Start' command.",
HostResources.ServiceName, ServiceControllerStatus.Stopped, ServiceControllerStatus.StopPending);
throw new HostServiceException(msg, HostServiceException.HostServiceExceptionCategory.ServiceStatusControl);
}
try
{
_hostController.Start();
}
catch (Exception ex)
{
if (ex is Win32Exception || ex is InvalidOperationException)
{
throw new HostServiceException(string.Format("'{0}' failed to respond properly to a 'StartService` command: '{1}'", _hostController.ServiceName, ex.Message), ex);
}
throw;
}
try
{
_hostController.WaitForStatus(ServiceControllerStatus.Running, _waitForStatusTimeout);
}
catch (TimeoutException tx)
{
throw new HostServiceException(string.Format("{0} did not start respond after {1} seconds and the 'Start' command timed out.", _hostController.ServiceName, _waitForStatusTimeout.TotalSeconds), tx);
}
if (ServiceControllerStatus.Running != _hostController.Status)
{
throw new HostServiceException(string.Format("The 'StartService' command for '{0}' failed. The Service has a status of '{1}'.", _hostController.ServiceName, _hostController.Status));
}
}
我的 WCF 服务有更简单的启动代码:
调度服务:
public void Start()
{
_isBusy = false;
var interval = _config.Settings.ServicePollingInterval * 1000;
_pollTimer = new Timer(interval);
_pollTimer.Enabled = true;
_pollTimer.Elapsed += PollTimerElapsed;
_pollTimer.Start();
Status = SchedulerServiceStatus.Running;
var msg = string.Format("'{0}' started with the timer set for {1} second{2} intervals.", SchedulerResources.ServiceName, _pollTimer.Interval / 1000, _pollTimer.Interval / 1000 > 1 ? "s" : "");
_logger.Info(msg);
StatusChanged(this, new SchedulerStatusChangeEventArgs(Status, msg));
}
这里是我的视图模型中的代码,因为只有它可以启动 Windows 服务,它才会启动 WCF 服务:
SchedulerViewModel:
private void ExecuteStart()
{
if (_hostModel.ServiceStatus != ServiceControllerStatus.Running)
{
_logger.Warn("The '" + _hostModel.ServiceName + "' host service is not running. The '" + GetType().Name + "' will attempt to start it.");
try
{
_hostModel.StartService();
}
catch (Exception ex)
{
var msg = string.Format("The '{0}' could not start the '{1}' host service: {2}", GetType().Name, _hostModel.ServiceName, ex.Message);
_logger.Error(msg, ex);
throw new HostServiceException(msg, HostServiceException.HostServiceExceptionCategory.ServiceController, ex);
}
}
try
{
_scheduler.Start();
}
catch (Exception ex)
{
throw new SchedulerServiceException(ex.Message, SchedulerServiceException.SchedulerServiceExceptionCategory.SchedulerControl, ex);
}
SchedulerStatus = _scheduler.Status;
CommandsCanExecuteChanged();
}
这确实不是视图逻辑,但也算不上业务逻辑;更像是家政服务:我只能在水源打开的情况下使用洗衣机。现在我真的不认为需要一个只有 HostModel
和 SchedulerService
实例的全新模型,只是为了这个决定。评审团对我当前的设置有何看法?
我会将所有代码推送到另一个服务后面,并通过接口将其注入到 VM 中,我这样做是因为我假设 WCF 通过事件公开状态并且您想在 UI.如果您将此推到另一个服务后面,则允许 'shape' 公开状态进入更 UI 适合在 VM 中使用的中心模型。
如果你这样做,从 VM 的角度来看,它所知道的只是 'start\stop' 方法和一个事件处理程序 - 然后实现被抽象出来,并通过模拟非常容易地测试 VM .
为了更进一步,我会考虑使用 Reactive 扩展而不是 CLR 事件来传达服务中的状态变化。