How do people structure their code when using the c# stateless library?
https://github.com/nblumhardt/stateless
I'm particularly interested in how this ties in with injected dependencies, and a correct approach of responsibilities and layering correctly.
My current structure involves the following:
public class AccountWf
{
private readonly AspNetUser aspNetUser;
private enum State { Unverified, VerificationRequestSent, Verfied, Registered }
private enum Trigger { VerificationRequest, VerificationComplete, RegistrationComplete }
private readonly StateMachine<State, Trigger> machine;
public AccountWf(AspNetUser aspNetUser, AccountWfService userAccountWfService)
{
this.aspNetUser = aspNetUser;
if (aspNetUser.WorkflowState == null)
{
aspNetUser.WorkflowState = State.Unverified.ToString();
}
machine = new StateMachine<State, Trigger>(
() => (State)Enum.Parse(typeof(State), aspNetUser.WorkflowState),
s => aspNetUser.WorkflowState = s.ToString()
);
machine.Configure(State.Unverified)
.Permit(Trigger.VerificationRequest, State.VerificationRequestSent);
machine.Configure(State.VerificationRequestSent)
.OnEntry(() => userAccountWfService.SendVerificationRequest(aspNetUser))
.PermitReentry(Trigger.VerificationRequest)
.Permit(Trigger.VerificationComplete, State.Verfied);
machine.Configure(State.Verfied)
.Permit(Trigger.RegistrationComplete, State.Registered);
}
public void VerificationRequest()
{
machine.Fire(Trigger.VerificationRequest);
}
public void VerificationComplete()
{
machine.Fire(Trigger.VerificationComplete);
}
public void RegistrationComplete()
{
machine.Fire(Trigger.RegistrationComplete);
}
}
Should we implement all processes (call to services) within the OnEntry hook, or implement the processes on the outside after the state transition has been verified that it is allowed to take place? I'm wonder how to do the transaction management if so.
I guess what I'm after is some best guidance from those who have already implemented something using stateless and how to approach the code structure.
Before addressing the structure itself a couple remarks:
OnEntry actions are only executed if the trigger has been successfully fired.
Triggers fired that are not allowed in the current state will throw an InvalidOperationException. Consider overriding OnUnhandledTrigger if you're not expecting an exception (I've found that logging unhandled triggers is a good approach to finding the flaws in the logic).
My rule of thumb for the OnEntry/OnExit structuring is that any creation and logic will be placed OnEntry and any required clean-up is done OnExit.
So in your case, given that the you're using injected dependencies (and assuming you're not taking ownership of those, i.e, someone else will manage their lifecycle) you can place all your logic OnEntry.
With that in mind, the way that your state machine is currently structured is perfectly fine.
One last note, keep in mind that firing triggers from within the same thread that's advancing the state machine and doing the state machine logic can and will lead to stackoverflow exceptions (see here on how to solve the auto advance issue).
Related
I'm using the prism framework for my WPF application with DryIoc, but maybe I don't quite understand some of it's uses. (Self-taught) or best practises.
I have a class library (MyLibrary) that follows a disposable pattern as it needs to do some clean-up.
I have a module that uses MyLibrary in its view model.
If the application is closed or even on an application crash, I would like to call dispose on this library, just in case it isn't already disposed of correctly at this time (otherwise it will leave third party apps open in the background)
There is currently only 1 instance, but could be more than 1 in the future.
So far, this is what I have come up with:
When my view model first requires MyLibrary it will register an instance, like so:
this.ce.RegisterInstance<MyLibrary>(this.myLibrary, "MyLibraryName"); where ce is Prism.Ioc.IContainerExtension
and then in the protected override void OnExit(ExitEventArgs e) method in my App.xaml.cs I will do: this.Container.Resolve<MyLibrary>("MyLibraryName")?.Dispose();
This successfully disposes my library object (and closes the 3rd party windows as i expect it to), however, it just seems a bit off to me (Code smell?)
Is there a better way to do it? I don't feel like the App.xaml.cs should have to know about the instance name that my module's view model came up with for example. Is there a way to just call Dispose on all MyLibrary types in the container without the name string?
I was hoping I could iterate over all MyLibrarys in the container and call Dispose?
If there isn't a better way then I'm ok with it I suppose.
But just as important: How can I attempt to call Dispose in a similar fashion on any unhandled exceptions that would otherwise crash the app? Can I access the container somehow and dispose of any MyLibrarys?
I wouldn't intend to try and save the app from crashing, just make sure that MyLibrary calls its Dispose method.
Comment response (Too many characters):
Click UI button> Delegate command> code written in method in VM.
The Library has an overhead to start up(sign in).
There are multiple input steps on the UI that requires use of the library.
Wrapping it in a using at each stage (button click) is not impossible, but it is inefficient because of the libraries startup overhead.
I want to:
- Instantiate library
- User inputs data, library does work, returns results, requires more input etc
- Several more of these data input stages / library work / results
- Dispose
Problem:
- User exits application before library object is disposed
- How/Where to dispose?
Attempted solution:
- Use the container so that i can dispose in App.xaml.cs `OnExit`
- This solution works, but feels incorrect?
Question: What can I do better/different in this situation?
Additional question: How do I handle disposing this upon a fatal crash in a prism app?
It's important that it gets disposed of so that instances of 3rd party apps that the library utilises are not left running in the background.
Ok, I changed it to register an instance in app.xaml.cs now and I can avoid the .Resolve call. Would you do it like this? If not then how? When it was registered as a singleton I had no idea how to get it in OnExit without the .Resolve
Cut-down/simplified example of my app.xaml.cs now:
namespace MyNamespace
{
public partial class App
{
public App()
{
// Crash handling
this.Dispatcher.UnhandledException += this.OnDispatcherUnhandledException;
}
// My library provider that contains a dictionary of library instances.
public IMyProvider MyProvider { get; set; } = new MyProvider();
// Dispose provider on crash
public void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
this.MyProvider.Dispose();
MessageBox.Show("Unhandled exception occurred: \n" + e.Exception.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
protected override Window CreateShell()
{
return this.Container.Resolve<MainWindow>();
}
// Register as an instance?
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterInstance<IMyProvider>(this.MyProvider);
}
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
// Add modules here...
}
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
// Dispose my provider (and all contained instances in its dictionary)
this.MyProvider.Dispose();
}
}
}
Comment character limit preventing me from writing too much again.
#Haukinger: tl;dr: You got me on the right track.
I didn't quite follow your example exactly to the letter (not using Lazy, library doesnt have an interface), but you got me on the right track.
Overall, I'm struggling to wrap my head around: DI, IoC, Interfaces and how they all relate.
Your line about abusing the container got me to look a little closer at it.
First, I removed all instances of containerExtension.resolve from view models and instead injected into the constructor as it should have always been.
I created a provider similar to what you suggested and a provider interface for my library.
The provider implementation keeps a dictionary of named library instances in case I require multiple.
I still call this.Container.Resolve<IMyProvider>().Dispose(); in the application's OnExit but it feels better because I don't have to name an instance any more.
Just having a provider interface still doesn't stop anyone from new-ing up library instances themselves though?
Library interface is registered like so:
containerRegistry.RegisterSingleton<IMyProvider, MyProvider>();
Other than my library:
I'm currently registering a few application wide instances for a few things like application theme in the container like so: containerRegistry.RegisterInstance<MyThing>(this.MyThing);
Still not using interfaces here. Still trying to understand them, but an application wide instance for theme in the container is working just fine.
From examples I've seen where IAnimal interface can have a Dog and a Cat implementation, my objects don't have multiple implementation requirements. (Besides unit testing which I'm yet to attempt to learn and I assume I will benefit from interfaces in this situation) I just need access to some things from different modules/assemblies and was using the container to do so.
One of my biggest problems was that I have parameters to construct some instances like my library and the parameters are not known until run time, so I couldn't register an instance in app.xaml.cs when the app starts.
If I have to construct something with parameters that are only known at runtime (credentials for example) Do I need to follow a sort of factory pattern with an interface to be able to register them or am I missing something?
I guess I could register an instance with the container extension at the time they get created (in assembly A's view model A)? but then I would need to use .Resolve later if I want them in a different module (Assembly B's view model X)?
Which doesn't feel right, and creating a factory and a factory interface for a simple credentials object feels overkill?
I think I'm just not fully understanding interfaces, as examples I've seen often dont have parameters for the implementation or they focus on discussing the benefits of different implementations when I will only have 1 implementation.
Or examples have nothing to do with IoC or DI.
As far as handling disposing on application crash event I did the following:
public App()
{
this.Dispatcher.UnhandledException += this.OnDispatcherUnhandledException;
}
public void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
// Dispose provider
this.Container.Resolve<IMyProvider>().Dispose();
// Unhandled exception messagebox:
MessageBox.Show("Unhandled exception occurred: \n" + e.Exception.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
I'm still tearing my hair out over interfaces / factory pattern / DI / Ioc / General design, but you got me on the right track.
I'm injecting stuff into constructors better, I can manage my library instances with the provider and dispose on exit and on crash is working.
Thanks.
I suggest you do not try to abuse the container here.
Instead, create a manager for your library yourself and clean that one up at shutdown:
public interface ILibraryProvider : IDisposable
{
ILibrary GetLibrary();
}
internal class LibraryProvider : ILibraryProvider
{
public LibraryProvider( Lazy<ILibrary> library )
{
_library = library;
}
#region ILibraryProvider
public ILibrary GetLibrary() => _library.Value;
public void Dispose()
{
if (_library.IsValueCreated)
_library.Value.Dispose();
}
#endregion
#region private
private readonly Lazy<ILibrary> _library;
#endregion
}
In Application.OnExit, dispose the LibraryManager.
If you need multiple, distinct libraries, add a string parameter to Get, inject a Func instead of a Lazy and store the instances in a Dictionary.
I am trying to change a string, being used for a title, in my blazor-server-side application. But I am having trouble getting the UI to update.
I tried using StateHasChanged(), but that didn't work so I looked around and found that on the FlightFinder Demo that was made, it has an OnChange event Action, so I am trying to implement that.
It works until I try to refresh the browser, then I am hit with this error
System.InvalidOperationException: 'The current thread is not associated with the renderer's synchronization context. Use Invoke() or InvokeAsync() to switch execution to the renderer's synchronization context when triggering rendering or modifying any state accessed during rendering.'
This is what I have:
private string _title = "TestSite";
public string Title => _title;
public event Action OnChange;
public void ChangePage(string pageName)
{
_title = pageName;
NotifyStateChanged();
}
private void NotifyStateChanged(int navigationType = 0)
{
OnChange?.Invoke();
}
All I have to do is call ChangePage("some Page Title") and it works, unless as I mentioned I try to refresh.
I am just trying to change a string on one component that through another component, which doesn't sound all that crazy. If there is a better way to do titles or change things from other components, I would love to hear about it.
So, what can I do to make sure that m invoke method is on the correct thread?
Or is there a different way to change the title that would be more effective?
Thank you in advance!
I have just implemented a State Container like this and ran into the same error - but my service needs to be a singleton.
So I found an example on the aspnetcore git that does exactly what the error message says to do.
Call InvokeAsync -- not from your state container but when you try to change the state of your razor component.
https://github.com/dotnet/aspnetcore/blob/321db9d99f84cf7a67d453384292d9339de748d1/src/Components/test/testassets/BasicTestApp/DispatchingComponent.razor
So your state container doesn't need to change, just your component event handler does.
#code{
protected override void OnInitialized()
{
_YourService.OnChange += OnMyChangeHandler;
}
public void Dispose()
{
_YourService.OnChange -= OnMyChangeHandler;
}
private async void OnMyChangeHandler(object sender, EventArgs e)
{
// InvokeAsync is inherited, it syncs the call back to the render thread
await InvokeAsync(() => {
DoStuff();
StateHasChanged();
});
}
}
Now your service (if it's a singleton) can notify ALL your users at once! Think about all hoops we had to jump through in past to do this.
I posted this first thing in the morning thinking that I wouldn't have the time to look into and thinking that by time someone was able to help me out, I would have found the time to look into it more. Though I have spent a couple of days going back and forth on this already.
I finally found this article that explains that what I am trying to do is called a State Container.
What they said is that I could inject the class as a singleton, which is what I was doing or a scoped service. Turns out all I needed to do was change it to a scoped service and it works great!
no need sophisticated solution, Blazor working perfectly if you will update GUI in your event handler by
this.InvokeAsync(() => this.StateHasChanged());
it worked using await InvokeAsync(stateHasChanged); in my case
I'm working in C# WPF with a proprietary framework (essentially a blend of Caliburn Micro and Castle Windsor) and I've got two singleton modules that have a race condition:
DeviceService - A service that manages a connection to a physical device emitting data. The service is "Startable" and hence is automatically constructed and initialized asynchronously.
ConnectionIndicatorViewModel - A client ViewModel that chiefly concerns itself with communicating to the user the status of the connection managed by DeviceService. Changes state mainly based on events fired by DeviceService.
My problem lies at application startup. In the constructor for the ViewModel, I set the default state to "Pending" because I assume that the Service has not finished initializing. Then the ViewModel simply handles the "Initialized" event fired by the Service. It's in this handler that I asses the actual connection state via a property on the Service and update the ViewModel.
Now, all of this works just fine because it is extremely unlikely that the race condition poke its head in. However, in the unlikely case that the Service finishes its initialization before the ViewModel is constructed, it will never handle that "Initialized" event and will just stay in its "Pending" state.
I've considered changing the Service interface to return awaitable types for properties, so that any module trying to access properties will have to wait for initialization to finish, but I'm not sure that this is the best approach. I'm also wary of having part of the client kick off the Service because then who should initialize it if several modules use it?
Is there some conventional way of dealing with this sort of asynchronous initialization that I am missing?
You mention using events to do the communication between the service and the ViewModel, you could use Reactive Extensions (Rx) instead of using events and this has the ability to remove the race condition you describe above.
Put simply this turns the service from a pull-model into a push-model, it will push out data\events via a stream and allows you to compose LINQ queries over the stream. If you're not familiar with Rx there's plenty of good information out.
In this scenario using Rx I would have the service expose a property of IObservable<T>;, where T is your type (I guess some kind of State enum), the backing field for this property is the important part, this would be a ReplaySubject<T> with a size of one. What this means is anytime someone 'subscribes' to the property they will receive the last value published to the subject. This therefore means there isn't a race condition between publishing and subscribing to the stream.
This is probably a little easier to understand in code:
public enum State
{
Initializing,
Initialized,
}
public interface IMyService
{
IObservable<State> Status { get; }
}
public class MyService : IMyService
{
private ReplaySubject<State> _state;
public MyService()
{
_state = new ReplaySubject<State>(1);
_state.OnNext(State.Initializing);
// Do initialisation stuff
_state.OnNext(State.Initialized);
}
public IObservable<State> Status { get { return _state; } }
}
The example only accounts for initializing the service on the current thread (ie synchronously), this means it would block the calling thread and I guess this would be the Dispatcher thread if this is a XAML based app.
If you require the initialization to be done asynchronously you would look to using either Observable.Create<T> or Observable.Start<T> to start the work on a background thread so that it doesn't block the dispatcher (UI) thread.
To consume this service you would do something like this is your ViewModel:
public class MyViewModel
{
private State _state;
public MyViewModel(IMyService myService)
{
myService.Status.ObserveOn(DispatcherScheduler.Current)
.Subscribe(x =>
{
_state = x;
});
}
public bool IsReady { get { return _state == State.Initialized; } }
}
Now there isn't a race condition between the Service and the ViewModel.
There can be a lot to learn about Reactive Extensions but it is a very good way to handle asynchronous calls when you're implementing an MVVM application.
I have an MVC3/.NET 4 application which uses Entity Framework (4.3.1 Code First)
I have wrapped EF into a Repository/UnitOfWork pattern as described here…
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Typically, as it explains in the article, when I require the creation of a new record I’ve been doing this…
public ActionResult Create(Course course)
{
unitOfWork.CourseRepository.Add(course);
unitOfWork.Save();
return RedirectToAction("Index");
}
However, when more than simply saving a record to a database is required I wrap the logic into what I’ve called an IService. For example…
private ICourseService courseService;
public ActionResult Create(Course course)
{
courseService.ProcessNewCourse(course);
return RedirectToAction("Index");
}
In one of my services I have something like the following…
public void ProcessNewCourse(Course course)
{
// Save the course to the database…
unitOfWork.CourseRepository.Add(course);
unitOfWork.Save();
// Generate a PDF that email some people about the new course being created, which requires more use of the unitOfWork…
var someInformation = unitOfWork.AnotherRepository.GetStuff();
var myPdfCreator = new PdfCreator();
IEnumerable<People> people = unitOfWork.PeopleRepository.GetAllThatWantNotifiying(course);
foreach(var person in people)
{
var message = “Hi ” + person.FullName;
var attachment = myPdfCreator.CreatePdf();
etc...
smtpClient.Send();
}
}
The above isn’t the actual code (my app has nothing to do with courses, I’m using view models, and I have separated the PDF creation and email message out into other classes) but the gist of what is going on is as above!
My problem is that the generation of the PDF and emailing it out is taking some time. The user just needs to know that the record has been saved to the database so I thought I would put the code below the unitOfWork.Save(); into an asynchronous method. The user can then be redirected and the server can happily take its time processing the emails, and attachments and whatever else I require it to do post save.
This is where I’m struggling.
I’ve tried a few things, the current being the following in ICourseService…
public class CourseService : ICourseService
{
private delegate void NotifyDelegate(Course course);
private NotifyDelegate notifyDelegate;
public CourseService()
{
notifyDelegate = new NotifyDelegate(this.Notify);
}
public void ProcessNewCourse(Course course)
{
// Save the course to the database…
unitOfWork.CourseRepository.Add(course);
unitOfWork.Save();
notifyDelegate.BeginInvoke(course);
}
private void Notify(Course course)
{
// All the stuff under unitOfWork.Save(); moved here.
}
}
My Questions/Problems
I’m randomly getting the error: "There is already an open DataReader associated with this Command which must be closed first." in the Notify() method.
Is it something to do with the fact that I’m trying to share the unitOrWork and therefore a dbContext across threads?
If so, can someone be kind enough to explain why this is a problem?
Should I be giving a new instance of unitOfWork to the Notify method?
Am I using the right patterns/classes to invoke the method asynchronously? Or should I be using something along the lines of....
new System.Threading.Tasks.Task(() => { Notify(course); }).Start();
I must say I've become very confused with the terms asynchronous, parallel, and concurrent!!
Any links to articles (c# async for idiots) would be appreciated!!
Many thanks.
UPDATE:
A little more digging got me to this SO page: https://stackoverflow.com/a/5491978/192999 which says...
"Be aware though that EF contexts are not thread safe, i.e. you cannot use the same context in more than one thread."
...so am I trying to achieve the impossible? Does this mean I should be creating a new IUnitOfWork instance for my new thread?
You could create a polling background thread that does the lengthy operation separately from your main flow. This thread could scan the database for new items (or items marked to process). This solution is pretty simple and ensures that jobs get done even if you application crashes (it will be picked up when the polling thread is started again).
You could also use a Synchronised Queue if it's not terrible if the request is 'lost', in the case your application crashes after the doc is requested and before it's generated/sent.
One thing is almost sure - as rikitikitik said - you will need to use a new unit of work, which means a separate transaction.
You could also look at Best threading queue example / best practice .
I am fairly new to Rx and am having trouble finding a solution to my problem. I am using Rx to commence a download through a client library. Currently it looks like:
private void DownloadStuff(string descriptor, Action<Stuff> stuffAction)
{
this.stuffDownloader.GetStuffObservable(descriptor).Subscribe(x => stuffAction(x))
}
Where stuffDownloader is a wrapper around download logic defined in the client library. But I encountered a problem where I call DownloadStuff too much, causing many downloads, and overwhelming the system. Now what I would like to do is
private void DownloadStuff(string descriptor, Action<Stuff> stuffAction)
{
this.stuffDownloader.GetStuffObservable(descriptor)
.SlowSubscribe(TimeSpan.FromMilliSeconds(50))
.Subscribe(x => stuffAction(x))
}
Where SlowSubscribe is some combination of Rx actions to only subscribe on some interval.
Normally I would just put these DownloadStuff calls on a queue and pull them off on an interval, but I've been trying to do more through Rx lately. Three solutions occur to me:
This functionality exists and can be done all on the subscription side.
This is possible but the infrastructure of the downloader is incorrect and should change (i.e. stuffDownloader needs to behave differently)
This shouldn't be done with Rx, do it another way.
It occurs to me #2 is possible by passing an IObservable of descriptors to the client library and somehow slowing how the descriptors get onto the Observable.
You could in theory use Rx to treat your requests as events. This way you could leverage the serializing nature of Rx to queue up downloads.
I would think that you network layer (or stuffDownloader) would do this for you, but if you want to join me for a hack....this is what I have come up with (Yeehaw!!)
1.
Dont pass an Action, use Rx!! You are basically losing the error handling here and setting yourself up for weird unhandled exceptions.
private void DownloadStuff(string descriptor, Action<Stuff> stuffAction)
becomes
private IObservable<Stuff> DownloadStuff(string descriptor)
2.
Now we just have one method calling another. Seems pointless. Throw away the abstraction.
3.
Fix the underlying. To me the stuffDownloader is not doing it's job. Update the interface to take an IScheduler. Now you can pass it a dedicated EventLoopScheduler to enforce the serialization of the work
public IObservable<Stuff> GetStuffObservable(string descriptor, IScheduler scheduler)
4.
Fix the implementation?
As you want to serialize your requests (hmmmm....) you can just make the call synchronous.
private Stuff GetSync(string description)
{
var request = (HttpWebRequest)WebRequest.Create("http://se300328:90/");
var response =request.GetResponse();
var stuff = MapToStuff(response);
return stuff;
}
Now you just call that in you other method
public IObservable<Stuff> GetStuffObservable(string descriptor, ISchedulerLongRunning scheduler)
{
return Observable.Create<Stuff>(o=>
{
try
{
var stuff = GetStuff(description);
o.OnNext(stuff);
o.OnCompleted();
}
catch(Exception ex)
{
o.OnError(ex);
}
return Disposable.Empty(); //If you want to be sync, you cant cancel!
})
.SubscribeOn(scheduler);
}
However, having done all of this, I am sure this is not what you really want. I would expect that there is a problem somewhere else in the system.
Another alternative is to consider using the Merge operator and it's max concurent feature?