Недавно я прочитал о библиотеке boost::statechart
(конечных автоматах), и мне понравилась эта концепция.
Есть ли в C # аналогичный механизм? Или это можно реализовать с помощью определенного шаблона проектирования?
Недавно я прочитал о библиотеке boost::statechart
(конечных автоматах), и мне понравилась эта концепция.
Есть ли в C # аналогичный механизм? Или это можно реализовать с помощью определенного шаблона проектирования?
Да, в C # есть блоки итераторов, которые являются конечными автоматами, сгенерированными компилятором.
Если вы хотите реализовать собственный конечный автомат, вы можете создавать собственные реализации интерфейсов IEnumerable<T>
и IEnumerator<T>
.
Оба этих подхода подчеркивают реализацию в платформе .NET шаблона итератора.
IEnumerable<T>
и IEnumerator<T>
.
- person Andrew Hare; 10.09.2009
.NET 4 Update 1 теперь поддерживает его в следующем классе: System.Activities.Statements.StateMachine
Вот руководство по его использованию. Вот практическая лабораторная работа.
Workflow Foundation (.NET 3.0) имеет рабочий процесс конечного автомата. В настоящее время в 4.0 нет того же самого, но вы определенно можете создать рабочий процесс конечного автомата, используя 4.0.
Я поддерживаю проект с открытым исходным кодом, который реализует (среди прочего) универсальный конечный автомат для .NET. Он построен на основе QuickGraph, поэтому вы бесплатно получаете множество алгоритмов анализа графиков.
Дополнительную информацию о проекте см. На этой странице, в частности о "Jolt.Automata: Finite State Machines" для получения дополнительной информации об этой функции.
Проверьте Stateless -> http://code.google.com/p/stateless/. Это легкая альтернатива более тяжелому WWF.
Вот пара статей автора инструмента:
Государственные машины в моделях предметной области
Параметризованные триггеры и состояния повторного входа в безгражданство
То, что приближается к конечным автоматам, - это рабочие процессы в .NET 3.5, однако рабочие процессы не совсем являются конечными автоматами.
Сила использования конечных автоматов заключается в том, что вы можете создавать их явно в своем коде, что снижает вероятность создания ошибок. Кроме того, конечно, некоторые системы по своей природе являются автоматами, поэтому их естественнее кодировать таким образом.
Windows Workflow Foundation (WF), которая является частью библиотеки базовых классов в версиях 3.0 и 3.5, включает дизайн рабочего процесса с конечным автоматом для управления конечными автоматами для ваших приложений.
Они полностью переписали рабочий процесс для предстоящей версии 4.0, и новые классы WF 4.0 не поддерживают машины состояний изначально, но все классы 3.0 / 3.5 по-прежнему полностью поддерживаются в 4.0.
Другая альтернатива в этом репо: https://github.com/lingkodsoft/StateBliss использует плавный синтаксис, поддерживает триггеры. .
public class BasicTests
{
[Fact]
public void Tests()
{
// Arrange
StateMachineManager.Register(new [] { typeof(BasicTests).Assembly }); //Register at bootstrap of your application, i.e. Startup
var currentState = AuthenticationState.Unauthenticated;
var nextState = AuthenticationState.Authenticated;
var data = new Dictionary<string, object>();
// Act
var changeInfo = StateMachineManager.Trigger(currentState, nextState, data);
// Assert
Assert.True(changeInfo.StateChangedSucceeded);
Assert.Equal("ChangingHandler1", changeInfo.Data["key1"]);
Assert.Equal("ChangingHandler2", changeInfo.Data["key2"]);
}
//this class gets regitered automatically by calling StateMachineManager.Register
public class AuthenticationStateDefinition : StateDefinition<AuthenticationState>
{
public override void Define(IStateFromBuilder<AuthenticationState> builder)
{
builder.From(AuthenticationState.Unauthenticated).To(AuthenticationState.Authenticated)
.Changing(this, a => a.ChangingHandler1)
.Changed(this, a => a.ChangedHandler1);
builder.OnEntering(AuthenticationState.Authenticated, this, a => a.OnEnteringHandler1);
builder.OnEntered(AuthenticationState.Authenticated, this, a => a.OnEnteredHandler1);
builder.OnExiting(AuthenticationState.Unauthenticated, this, a => a.OnExitingHandler1);
builder.OnExited(AuthenticationState.Authenticated, this, a => a.OnExitedHandler1);
builder.OnEditing(AuthenticationState.Authenticated, this, a => a.OnEditingHandler1);
builder.OnEdited(AuthenticationState.Authenticated, this, a => a.OnEditedHandler1);
builder.ThrowExceptionWhenDiscontinued = true;
}
private void ChangingHandler1(StateChangeGuardInfo<AuthenticationState> changeinfo)
{
var data = changeinfo.DataAs<Dictionary<string, object>>();
data["key1"] = "ChangingHandler1";
}
private void OnEnteringHandler1(StateChangeGuardInfo<AuthenticationState> changeinfo)
{
// changeinfo.Continue = false; //this will prevent changing the state
}
private void OnEditedHandler1(StateChangeInfo<AuthenticationState> changeinfo)
{
}
private void OnExitedHandler1(StateChangeInfo<AuthenticationState> changeinfo)
{
}
private void OnEnteredHandler1(StateChangeInfo<AuthenticationState> changeinfo)
{
}
private void OnEditingHandler1(StateChangeGuardInfo<AuthenticationState> changeinfo)
{
}
private void OnExitingHandler1(StateChangeGuardInfo<AuthenticationState> changeinfo)
{
}
private void ChangedHandler1(StateChangeInfo<AuthenticationState> changeinfo)
{
}
}
public class AnotherAuthenticationStateDefinition : StateDefinition<AuthenticationState>
{
public override void Define(IStateFromBuilder<AuthenticationState> builder)
{
builder.From(AuthenticationState.Unauthenticated).To(AuthenticationState.Authenticated)
.Changing(this, a => a.ChangingHandler2);
}
private void ChangingHandler2(StateChangeGuardInfo<AuthenticationState> changeinfo)
{
var data = changeinfo.DataAs<Dictionary<string, object>>();
data["key2"] = "ChangingHandler2";
}
}
}
public enum AuthenticationState
{
Unauthenticated,
Authenticated
}
}