Can someone who is either familiar with Fluxor or C# Dependency Injection help me with an issue that I've struggled with for several days please.
When you use Fluxor within a Blazor Component you include the following to raise an Action:
@Inherits Blazor.Fluxor.Components.FluxorComponent
@Inject IDisptacher dispatcher
That allows you to raise an Action within the Component with: Dispatcher.Dispatch(new MyAction(MyParameter))
;
In addition to dispatching Fluxor Actions from a Blazor Component (which I have working well), I need to be able to dispatch an Action from a regular class in a .cs file. I've tried Injection as shown in the following TestClass but a NullReferenceException
is raised when Dispatcher.Dispatch
is hit.
using Fluxor;
using Microsoft.AspNetCore.Components;
namespace ICET.Store
{
public class TestClass
{
[Inject]
private IDispatcher Dispatcher { get; set; }
public void onMessage()
{
// Other code removed
Dispatcher.Dispatch(new LoggedInAction(phoneNumber));
}
}
}
Clearly something has to instantiate the Dispatcher declared with private IDispatcher Dispatcher { get; set; }
but I thought that instantiation happened in the Startup.cs with the following:
services.AddFluxor(options =>
{
options.UseDependencyInjection(typeof(Startup).Assembly)
{);
Clearly I missing something here but I'm stumped with what that is. Can someone give me some guidance about how a Fluxor Action can be raised within a Class included in a regular .cs file. Thanks.
Using Constructor Injection as suggested by Peter Morris I've altered my Test Class to:
public class TestClass
{
IDispatcher _dispatcher;
public TestClass(IDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
public void onMessage()
{
// Other code removed
_dispatcher.Dispatch(new LoggedInAction());
}
}
However, what I'm struggling with now is when I instantiate my Class how do I get a reference to a Fluxor Disptacher that I can pass to the TestClass Constructor? I thought as Fluxor is implemented as a Service ie;
services.AddFluxor(options =>
{
options.UseDependencyInjection(typeof(Startup).Assembly)
{);
... that's it somehow available globally to reference.
Next update ...
My TestClass has been altered to implement an Interface and is now registered as a Scoped Service in Startup.cs
public interface ITestClass
{
public void InitiateAction();
}
public class TestClass : ITestClass
{
IDispatcher _dispatcher;
public TestClass(IDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
public void InitiateAction()
{
_dispatcher.Dispatch(new LoggedInAction("123456"));
}
}
Startup.cs
services.AddScoped<ITestClass, TestClass>();
As a result of these changes I was expecting the TestClass would have been instantiated and I'd be able to call its InitiateAction
method to Dispatch an Action. However, it remains stubbornly null in the following code:
class DeviceListener : Cometd.Bayeux.Client.IMessageListener
{
private readonly IDispatcher _dispatcher;
private ITestClass _testClass;
public void onMessage(Cometd.Bayeux.Client.IClientSessionChannel mChannel, Cometd.Bayeux.IMessage message)
{
_testClass.InitiateAction();
}
Update ... My DeviceListener class implements the Cometd.Bayeux.Client.IMessageListener interface and defines a Callback which is executed when an unsolicited message is received from a server process. It's referenced in Startup.cs:
listener = mClient.getChannel("/v2/me/devices");
listener.subscribe(new GWS.DeviceListener());
The class is structured as follows:
class DeviceListener : Cometd.Bayeux.Client.IMessageListener
{
private readonly IDispatcher _dispatcher;
public DeviceListener(IDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
public void onMessage(Cometd.Bayeux.Client.IClientSessionChannel mChannel, Cometd.Bayeux.IMessage message)
{
_dispatcher.Dispatch(new LoggedInAction("12345");
}
}
All illustrated in the above DeviceListener, I want to be able to dispatch a Fluxor Action from within onMessage
.
The above DeviceListener shows a parameterized Constructor but that actually causes an argument compile error against listener.subscribe(new GWS.DeviceListener());
in Startup.cs