I'm introducing Spring Statemachine into an existing project, with the hope of amalgamating and clarifying our business logic. We have various JPA entities with interconnected states and I'm having some trouble with setting a persisted state as the current state of an existing state machine.
I'm using a StateMachineFactory to create a new StateMachine instance for each entity instance. I'm storing the current state of the StateMachine in a separate field for Hibernate to persist and ideally need to sync the value of the persisted field with the StateMachine. My question is around how this should be typically achieved in Spring Statemachine.
#Entity
#EntityListeners(MyEntityListener.class)
public class MyEntity {
#Column
private MyState internalState; // Using AttributeConverter
#Transient
private StateMachine<MyState, Event> stateMachine;
}
public class MyEntityListener {
#PostLoad
public void postLoad(MyEntity entity) {
// TODO Set StateMachine's current state to entity's internal state
);
}
One approach may be to define local transitions to move the initial state into the persisted state. I could then do a conditional check to find an event tied to a local transition, which would move the source state into the target state. This seems a little messy to me and I'd like to keep my state machine's configuration as clean as possible.
I can't see how I can set the StateMachine's current state through a public API without moving through a transition and so another approach I explored is to wrap the StateMachine instance to expose the following method (as it's conveniently default scope):
package org.springframework.statemachine.support;
public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSupport<S, E> implements StateMachine<S, E>, StateMachineAccess<S, E> {
void setCurrentState(State<S, E> state, Message<E> message, Transition<S, E> transition, boolean exit, StateMachine<S, E> stateMachine)
}
package org.springframework.statemachine.support;
public class MyStateMachineWrapper<S, E> {
private AbstractStateMachine<S, E> stateMachine;
public MyStateMachineWrapper(StateMachine<S, E> stateMachine) {
if (stateMachine instanceof AbstractStateMachine) {
this.stateMachine = (AbstractStateMachine<S, E>)stateMachine;
} else {
throw new IllegalArgumentException("Provided StateMachine is not a valid type");
}
}
public void setCurrentState(S status) {
stateMachine.setCurrentState(findState(status), null, null, false, stateMachine);
}
private State<S, E> findState(S status) {
for (State<S, E> state : stateMachine.getStates()) {
if (state.getId() == status) {
return state;
}
}
throw new IllegalArgumentException("Specified status does not equate to valid State");
}
}
I could then throw the following code into MyEntityListener.postLoad:
MyStateMachineWrapper<MyState, Event> myStateMachineWrapper = new MyStateMachineWrapper<>(entity.getStateMachine());
myStateMachineWrapper.setCurrentState(entity.getInternalState());
The above approach seems to work fine but I can't imagine this is how it was envisioned to work. Surely there's a cleaner method to achieve this or maybe the project isn't mature enough and doesn't include this functionality yet?
Thanks for any thoughts and opinions.
I've cleaned up option #2 above, changing the wrapper class to a utils class. To be clear, this approach takes advantage of the setCurrentState method having a default accessor and so this may end up being a brittle solution.
package org.springframework.statemachine.support;
public abstract class MyStateMachineUtils extends StateMachineUtils {
public static <S, E> void setCurrentState(StateMachine<S, E> stateMachine, S state) {
if (stateMachine instanceof AbstractStateMachine) {
setCurrentState((AbstractStateMachine<S, E>)stateMachine, state);
} else {
throw new IllegalArgumentException("Provided StateMachine is not a valid type");
}
}
public static <S, E> void setCurrentState(AbstractStateMachine<S, E> stateMachine, S state) {
stateMachine.setCurrentState(findState(stateMachine, state), null, null, false, stateMachine);
}
private static <S, E> State<S, E> findState(AbstractStateMachine<S, E> stateMachine, S stateId) {
for (State<S, E> state : stateMachine.getStates()) {
if (state.getId() == stateId) {
return state;
}
}
throw new IllegalArgumentException("Specified State ID is not valid");
}
}
This can then be used quite nicely like so:
MyStateMachineUtils.setCurrentState(entity.getStateMachine(), entity.getInternalState());
Related
I'm working on a .NET Core 2.2 Console Application that hosts an IHostedService:
public class MqttClientHostedService : IHostedService, IDisposable
{
[...]
public MqttClientHostedService(
ILogger<MqttClientHostedService> logger,
IOptions<MqttClientConfiguration> mqttConfiguration,
IPositionService positionService)
{
this.logger = logger;
this.config = mqttConfiguration;
this.positionService = positionService;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
mqttClient = new MqttFactory().CreateMqttClient();
mqttClient.Connected += async (s, e) => await MqttClient_Connected(s, e);
mqttClient.ApplicationMessageReceived +=
async (s, e) => await MqttClient_ApplicationMessageReceived(s, e);
await mqttClient.ConnectAsync(
new MqttClientOptionsBuilder()
.WithTcpServer(config.Value.Host, config.Value.Port).Build());
}
private async Task MqttClient_ApplicationMessageReceived(
object sender, MqttApplicationMessageReceivedEventArgs e)
{
string message = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
await positionService.HandleMessage(message);
}
[...]
}
This IPositionService is a manager that inspects the message and checks if it can be saved inside our database:
public class PositionService : IPositionService
{
[...]
public PositionService(
IUnitOfWork unitOfWork, ILogger<PositionService> logger)
{
this.unitOfWork = unitOfWork;
this.logger = logger;
}
public async Task HandleMessage(string message)
{
Entity entity = await unitOfWork.EntityRepository.GetByMessage(message);
[...]
await unitOfWork.EntityRepository.UpdateAsync(entity);
await unitOfWork.Save();
}
[...]
}
IUnitOfWork is a wrapper around Entity Framework Core DbContext (please don't judge me, I have reasons to do this):
public class UnitOfWork : IUnitOfWork
{
[...]
public UnitOfWork(MyContext myContext)
{
this.myContext = myContext;
EntityRepository = new EFRepository<Entity>(myContext);
}
public async Task Save()
{
await myContext.SaveChangesAsync();
}
}
EFRepository<T>, that implements IRepository<T> interface, is a wrapper around DbSet<T> (again, please don't judge me). No relevant code here.
Console Application's Program.cs is configured like that:
[...]
.ConfigureServices((hostContext, services) =>
{
services.AddDbContext<MyContext>(
c => c.UseSqlServer("[...]", options => options.UseNetTopologySuite()),
ServiceLifetime.Transient);
services.AddTransient<IPositionService, PositionService>();
services.AddTransient(typeof(IRepository<>), typeof(EFRepository<>));
services.AddTransient<IUnitOfWork, UnitOfWork>();
services.AddHostedService<MqttClientHostedService>();
[...]
});
Problem is that PositionService.HandleMessage is being called many times per second, and being that DbContext is not thread safe I get this error message:
A second operation started on this context before a previous operation
completed.
I solved this issue by removing IUnitOfWork from PositionService's dependencies, injecting instead an IServiceScopeFactory, and doing:
using (IServiceScope serviceScope = serviceScopeFactory.CreateScope())
{
IUnitOfWork unitOfWork = serviceScope.ServiceProvider.GetService<IUnitOfWork>();
[...]
}
This way works, but I don't like it. It seems like a trick, and I don't like the fact that my PositionService knows about Dependency Injection and has to deal with scopes.
My question is: there's a better way to solve this problem without touching my classes? Should I make the whole UnitOfWork thread safe? Or maybe create it by hand without using DI?
The source of the problem is that MyContext is held captive as a Captive Dependency in the following object graph:
MqttClientHostedService
-> PositionService
-> UnitOfWork
-> MyContext
All types in this graph are registered as Transient, but still, services that act as hosted service (e.g. your MqttClientHostedService) are resolved only once for the duration of the application and cached indefinately. This effectively makes them a singleton.
In other words, MyContext is accidentally kept alive by the single MqttClientHostedService and because multiple messages can come in in parallel, you have yourself a race condition.
The solution is to let each ApplicationMessageReceived event run in its own unique little bubble (a scope) and resolve a new IPositionService from within that bubble. For instance:
public class MqttClientHostedService : IHostedService, IDisposable
{
[...]
public MqttClientHostedService(
ILogger<MqttClientHostedService> logger,
IOptions<MqttClientConfiguration> mqttConfiguration,
IServiceProvider provider)
{
this.logger = logger;
this.config = mqttConfiguration;
this.provider = provider;
}
[...]
private async Task MqttClient_ApplicationMessageReceived(
object sender, MqttApplicationMessageReceivedEventArgs e)
{
using (var scope = provider.CreateScope())
{
positionService = scope.ServiceProvider
.GetRequiredService<IPositionService>();
string message = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
await positionService.HandleMessage(message);
}
}
[...]
}
I need to create a custom IObservable. I've read a bit over there, I've ended up I shouldn't implement IObservable<T> directly.
I've noticed that there is an ObservableBase<T>. This is an abstract class, so I need to implement the abstract method:
public class Store<TState> : ObservableBase<TState>, IObserver<IAction>
{
public void OnCompleted()
{
throw new NotImplementedException();
}
public void OnError(Exception error)
{
throw new NotImplementedException();
}
public void OnNext(IAction value)
{
throw new NotImplementedException();
}
protected override IDisposable SubscribeCore(IObserver<TState> observer)
{
>>>>>>>>>>>>>>>>>******<<<<<<<<<<<<<<<<<<<<<<<
throw new NotImplementedException();
}
}
How should I implement this method?
I don't know your problem, but if you can replace implementing IObservable for exposing a property/method that returns IObservable you'll be a lot better off. If you can do that, you can easily return an Rx-based Observable from some of Rx's create methods.
If you can't do that, I would recommend wrapping a Subject<T>:
public class MyIntObservable : IObservable<int>
{
private readonly Subject<int> _mySubject = new Subject<int>();
public IDisposable Subscribe(IObserver<int> observer)
{
return _mySubject.Subscribe(observer);
}
}
I'm guessing you don't want to be doing what you are doing.
From a brief look at the "Store" class that you want to mimic, it appears to be some sort of Subject. A Subject is both a IObserver and an IObservable and there are many implementations that are provided out of the box. Here is the interface:
public interface ISubject<in TSource, out TResult> : IObserver<TSource>, IObservable<TResult>
{
}
This is a very good article about Subjects and when to use them here:
http://davesexton.com/blog/post/To-Use-Subject-Or-Not-To-Use-Subject.aspx
I wanted to know if this was thread safe/ good practice. My IOC is ninject, everything service layer call is via the default setting (In transient scope I think?).
Question, is instantiating new FileAllocation(loggedonuser,_repo) correct? The best way? What is the best way to do this? This is a domain class that holds logic that could be called from various services, there are usually a few database calls involved, most of the time no persistance is necessary...
Anyway, I call my service method via an interface e.g.
void SaveFile(int reportid, stream file); //Interface name: IReportFileService
public Class FileService: Servicebase, IReportFileService
{
private readonly IRepoSession _repo;
public FileService(IUserSession user, IRepoSession repo, IUpdateSession update)
: base(user,update)
{
_repo = repo;
}
//save file if users 'counter' is ok..
public void SaveFile(int reportid, stream file)
{
//here I want to instantiate a new class that I store in my domain and store the counters
//etc and do related db calls to check up relevant values
//note loggedonuser is a prop on my *base class*
var userChecks = new FileAllocation(loggedonuser,_repo);
userChecks.CountEmUp(); //exception is thrown if 0, less than "limit" etc...
base.update(userChecks.mycompany); //persist
base.commit(); //base class method includes try, catch block...
}
}
public class FileAllocation
{
private readonly IRepoSession _repo;
private readonly Loggedonuser _user;
private int CompanyUploads;
private int UserUploads;
public Company mycompany;
public FileAllocation(Loggedonuser user, IRepoSession repo)
{
_repo = repo;
_user = user;
}
public void CountEmUp()
{
//do error checking,
//load up other tables can user upload - permissions, count is ok etc...
// check the upload type if of certain type we cannot proceed - call another method on this class
//set myCompany variable to new limits etc...
}
}
Base Service includes a prop, I dont want to instantiate this from other services i.e. more that once, how do I avoid that?
private LoggedonuserDTO _currentuser = null;
protected LoggedonuserDTO loggedonuser
{
get
{
if (_currentuser == null)
{
_currentuser = _user.GetCurrentUser(); //make db call here...
}
return _currentuser;
}
}
#Darin suggested:
public interface IFileAllocation
{
CountEmUp(Loggedonuser currentuser);
}
//pass in loggedonuser to any method that requires it...
public class FileAllocation: IFileAllocation
{
CountEmUp(Loggedonuser currentuser)
{
//do whatever here...
}
}
var userChecks = new FileAllocation(loggedonuser,_repo);
introduces a strong coupling between the FileService and the FileAllocation classes. If this is not a problem for you then you can leave it that way. Otherwise you could abstract the operations of this FileAllocation class into an interface and then inject it into FileService. This way the FileService is weakly coupled with FileAllocation and could be reused in different contexts and unit tested in isolation.
I'm using StructureMap to resolve references to my repository class. My repository interface implements IDisposable, e.g.
public interface IMyRepository : IDisposable
{
SomeClass GetById(int id);
}
An implementation of the interface using Entity Framework:
public MyRepository : IMyRepository
{
private MyDbContext _dbContext;
public MyDbContext()
{
_dbContext = new MyDbContext();
}
public SomeClass GetById(int id)
{
var query = from x in _dbContext
where x.Id = id
select x;
return x.FirstOrDefault();
}
public void Dispose()
{
_dbContext.Dispose();
}
}
Anyway as mentioned I'm using StructureMap to resolve IMyRepository. So when, where and how should I call my dispose method?
WARNING: please note that my views have changed, and you should consider the following advise outdated. Please see this answer for an updated view: https://stackoverflow.com/a/30287923/264697
While DI frameworks can manage lifetime of objects for you and some could even dispose objects for you after you're done using with them, it makes object disposal just too implicit. The IDisposable interface is created because there was the need of deterministic clean-up of resources. Therefore, in the context of DI, I personally like to make this clean-up very explicit. When you make it explicit, you've got basically two options: 1. Configure the DI to return transient objects and dispose these objects yourself. 2. Configure a factory and instruct the factory to create new instances.
I favor the second approach over the first, because especially when doing Dependency Injection, your code isn't as clean as it could be. Look for instance at this code:
public sealed class Client : IDisposable
{
private readonly IDependency dependency;
public Client(IDependency dependency)
{
this. dependency = dependency;
}
public void Do()
{
this.dependency.DoSomething();
}
public Dispose()
{
this.dependency.Dispose();
}
}
While this code explicitly disposes the dependency, it could raise some eyebrows to readers, because resources should normally only be disposed by the owner of the resource. Apparently, the Client became the owner of the resource, when it was injected.
Because of this, I favor the use of a factory. Look for instance at this example:
public sealed class Client
{
private readonly IDependencyFactory factory;
public Client(IDependencyFactory factory)
{
this.factory = factory;
}
public void Do()
{
using (var dependency = this.factory.CreateNew())
{
dependency.DoSomething();
}
}
}
This example has the exact same behavior as the previous example, but see how the Client class doesn't have to implement IDisposable anymore, because it creates and disposes the resource within the Do method.
Injecting a factory is the most explicit way (the path of least surprise) to do this. That's why I prefer this style. Downside of this is that you often need to define more classes (for your factories), but I personally don't mind.
RPM1984 asked for a more concrete example.
I would not have the repository implement IDisposable, but have a Unit of Work that implements IDisposable, controls/contains repositories and have a factory that knows how to create new unit of works. With that in mind, the above code would look like this:
public sealed class Client
{
private readonly INorthwindUnitOfWorkFactory factory;
public Client(INorthwindUnitOfWorkFactory factory)
{
this.factory = factory;
}
public void Do()
{
using (NorthwindUnitOfWork db =
this.factory.CreateNew())
{
// 'Customers' is a repository.
var customer = db.Customers.GetById(1);
customer.Name = ".NET Junkie";
db.SubmitChanges();
}
}
}
In the design I use, and have described here, I use a concrete NorthwindUnitOfWork class that wraps an IDataMapper that is the gateway to the underlying LINQ provider (such as LINQ to SQL or Entity Framework). In sumary, the design is as follows:
An INorthwindUnitOfWorkFactory is injected in a client.
The particular implementation of that factory creates a concrete NorthwindUnitOfWork class and injects a O/RM specific IDataMapper class into it.
The NorthwindUnitOfWork is in fact a type-safe wrapper around the IDataMapper and the NorthwindUnitOfWork requests the IDataMapper for repositories and forwards requests to submit changes and dispose to the mapper.
The IDataMapper returns Repository<T> classes and a repository implements IQueryable<T> to allow the client to use LINQ over the repository.
The specific implementation of the IDataMapper holds a reference to the O/RM specific unit of work (for instance EF's ObjectContext). For that reason the IDataMapper must implement IDisposable.
This results in the following design:
public interface INorthwindUnitOfWorkFactory
{
NorthwindUnitOfWork CreateNew();
}
public interface IDataMapper : IDisposable
{
Repository<T> GetRepository<T>() where T : class;
void Save();
}
public abstract class Repository<T> : IQueryable<T>
where T : class
{
private readonly IQueryable<T> query;
protected Repository(IQueryable<T> query)
{
this.query = query;
}
public abstract void InsertOnSubmit(T entity);
public abstract void DeleteOnSubmit(T entity);
// IQueryable<T> members omitted.
}
The NorthwindUnitOfWork is a concrete class that contains properties to specific repositories, such as Customers, Orders, etc:
public sealed class NorthwindUnitOfWork : IDisposable
{
private readonly IDataMapper mapper;
public NorthwindUnitOfWork(IDataMapper mapper)
{
this.mapper = mapper;
}
// Repository properties here:
public Repository<Customer> Customers
{
get { return this.mapper.GetRepository<Customer>(); }
}
public void Dispose()
{
this.mapper.Dispose();
}
}
What's left is an concrete implementation of the INorthwindUnitOfWorkFactory and a concrete implementation of the IDataMapper. Here's one for Entity Framework:
public class EntityFrameworkNorthwindUnitOfWorkFactory
: INorthwindUnitOfWorkFactory
{
public NorthwindUnitOfWork CreateNew()
{
var db = new ObjectContext("name=NorthwindEntities");
db.DefaultContainerName = "NorthwindEntities";
var mapper = new EntityFrameworkDataMapper(db);
return new NorthwindUnitOfWork(mapper);
}
}
And the EntityFrameworkDataMapper:
public sealed class EntityFrameworkDataMapper : IDataMapper
{
private readonly ObjectContext context;
public EntityFrameworkDataMapper(ObjectContext context)
{
this.context = context;
}
public void Save()
{
this.context.SaveChanges();
}
public void Dispose()
{
this.context.Dispose();
}
public Repository<T> GetRepository<T>() where T : class
{
string setName = this.GetEntitySetName<T>();
var query = this.context.CreateQuery<T>(setName);
return new EntityRepository<T>(query, setName);
}
private string GetEntitySetName<T>()
{
EntityContainer container =
this.context.MetadataWorkspace.GetEntityContainer(
this.context.DefaultContainerName, DataSpace.CSpace);
return (
from item in container.BaseEntitySets
where item.ElementType.Name == typeof(T).Name
select item.Name).First();
}
private sealed class EntityRepository<T>
: Repository<T> where T : class
{
private readonly ObjectQuery<T> query;
private readonly string entitySetName;
public EntityRepository(ObjectQuery<T> query,
string entitySetName) : base(query)
{
this.query = query;
this.entitySetName = entitySetName;
}
public override void InsertOnSubmit(T entity)
{
this.query.Context.AddObject(entitySetName, entity);
}
public override void DeleteOnSubmit(T entity)
{
this.query.Context.DeleteObject(entity);
}
}
}
You can find more information about this model here.
UPDATE December 2012
This an an update written two years after my original answer. The last two years much has changed in the way I try to design the systems I'm working on. Although it has suited me in the past, I don't like to use the factory approach anymore when dealing with the Unit of Work pattern. Instead I simply inject a Unit of Work instance into consumers directly. Whether this design is feasibly for you however, depends a lot on the way your system is designed. If you want to read more about this, please take a look at this newer Stackoverflow answer of mine: One DbContext per web request…why?
If you want to get it right, i'd advise on a couple of changes:
1 - Don't have private instances of the data context in the repository. If your working with multiple repositories then you'll end up with multiple contexts.
2 - To solve the above - wrap the context in a Unit of Work. Pass the unit of work to the Repositories via the ctor: public MyRepository(IUnitOfWork uow)
3 - Make the Unit of Work implement IDisposable. The Unit of Work should be "newed up" when a request begins, and therefore should be disposed when the request finishes. The Repository should not implement IDisposable, as it is not directly working with resources - it is simply mitigating them. The DataContext / Unit of Work should implement IDispoable.
4 - Assuming you are using a web application, you do not need to explicitly call dispose - i repeat, you do not need to explicitly call your dispose method. StructureMap has a method called HttpContextBuildPolicy.DisposeAndClearAll();. What this does is invoke the "Dispose" method on any HTTP-scoped objects that implement IDisposable. Stick this call in Application_EndRequest (Global.asax). Also - i believe there is an updated method, called ReleaseAllHttpScopedObjects or something - can't remember the name.
Instead of adding Dispose to IMyRepository, you could declare IMyRepository like this:
public interface IMyRepository: IDisposable
{
SomeClass GetById(int id);
}
This way, you ensure all repository will call Dispose sometimes, and you can use the C# "using" pattern on a Repository object:
using (IMyRepository rep = GetMyRepository(...))
{
... do some work with rep
}
I've looked at Ninject, StructureMap and Other Dependency Injection and Service Locator frameworks, but this question is more about learning how it works and what can be better. More to the point, I’m not interesting in looking at a Framework’s source code for Dependency Injection, but understanding how it’s achieved from beginning to end in practice/code.
The code below is for a small internal project, so with that in mind let me begin.
Here is my interface for returning Domain Models to my controllers. I've decided that due to the size of the project (small), a single interface for Controllers was acceptable.
interface IModelFactory
{
IEnumerable<User> GetUsers();
User GetUser(Guid UserID);
bool Add(User User);
bool Delete(User User);
bool Update(User User);
IEnumerable<Car> GetCars();
Car GetCar(Guid CarID);
bool Add(Car Car);
bool Delete(Car Car);
bool Update(Car Car);
}
Each controller has inherits from DIBaseController so I didn't have to create private members for every controller.
public abstract class DIBaseController : Controller
{
protected IModelFactory ModelFactory { get; set; }
public DIBaseController(IModelFactory ModelFactory)
{
this.ModelFactory = ModelFactory;
}
}
public class HomeController : DIBaseController
{
public HomeController (IModelFactory ModelFactory)
: base(ModelFactory)
{
}
}
Created my own Controller Factory that allows me to inject my ModelFactory into Controllers.
internal class DIControllerFactory : DefaultControllerFactory
{
private IModelFactory _ModelFactory;
internal DIControllerFactory(IModelFactory ModelFactory)
{
this._ModelFactory = ModelFactory;
}
public override IController CreateController(RequestContext requestContext, string controllerName)
{
IController result = null;
string thisnamespace = this.GetType().Namespace;
//This could be improved I bet.
Type controller = Type.GetType(thisnamespace.Substring(0, thisnamespace.IndexOf('.')) + ".Controllers." + controllerName + "Controller");
if (controller != null
&& controller.IsSubclassOf(typeof(DIBaseController)))
{
result = (IController)Activator.CreateInstance(controller, new object[] { this._ModelFactory });
}
else
{
result = base.CreateController(requestContext, controllerName);
}
return result;
}
}
And finally added the code to Inject the Concreate class into the Factory to inject into created Controllers.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new DIControllerFactory(new LinqSqlModelFactory()));
}
The only area I haven't explored (and I don't think I'm interested in at the moment) is to create a web.config section to dynamically create the ModelFactory. This works, but I'm interested if I've completely missed the boat, come close, or if I'm spot on?
Instead of overriding CreateController use
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
It gives you the controller type and the first part of your implementation is obsolete.
The next point you have to improve is that you analyze the parameters of the constructor and pass an instance of those parameters which are created using some configuration instead of guessing that there is exactly one parameter IModelFactory.