这是我的视图模型中的业务逻辑吗,是否允许这样做?

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

这确实不是视图逻辑,但也算不上业务逻辑;更像是家政服务:我只能在水源打开的情况下使用洗衣机。现在我真的不认为需要一个只有 HostModelSchedulerService 实例的全新模型,只是为了这个决定。评审团对我当前的设置有何看法?

我会将所有代码推送到另一个服务后面,并通过接口将其注入到 VM 中,我这样做是因为我假设 WCF 通过事件公开状态并且您想在 UI.如果您将此推到另一个服务后面,则允许 'shape' 公开状态进入更 UI 适合在 VM 中使用的中心模型。

如果你这样做,从 VM 的角度来看,它所知道的只是 'start\stop' 方法和一个事件处理程序 - 然后实现被抽象出来,并通过模拟非常容易地测试 VM .

为了更进一步,我会考虑使用 Reactive 扩展而不是 CLR 事件来传达服务中的状态变化。