2

请熟悉 Fluxor 或 C# Dependency Injection 的人帮助我解决我困扰了几天的问题。

在 Blazor 组件中使用 Fluxor 时,您可以包含以下内容来引发操作:

@Inherits Blazor.Fluxor.Components.FluxorComponent
@Inject IDisptacher dispatcher

这允许您在组件内引发一个动作 Dispatcher.Dispatch(new MyAction(MyParameter))

除了从 Blazor 组件分派 Fluxor Actions(我工作得很好)之外,我还需要能够从 .cs 文件中的常规类分派 Action。我已经尝试过注入,如下面的 TestClass 所示,但是在被击中NullReferenceException时会引发a 。Dispatcher.Dispatch

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

显然,必须实例化声明的 Dispatcher,private IDispatcher Dispatcher { get; set; }但我认为实例化发生在 Startup.cs 中,如下所示:

services.AddFluxor(options =>
{
   options.UseDependencyInjection(typeof(Startup).Assembly)
{);

显然我在这里遗漏了一些东西,但我对那是什么感到困惑。有人可以给我一些关于如何在常规 .cs 文件中包含的类中引发 Fluxor Action 的指导。谢谢。

使用 Peter Morris 建议的构造函数注入,我将测试类更改为:

public class TestClass
    {
        IDispatcher _dispatcher;

        public TestClass(IDispatcher dispatcher)
        {
            _dispatcher = dispatcher;    
        }
    
        public void onMessage()
        {
            // Other code removed

            _dispatcher.Dispatch(new LoggedInAction());
        }
    }

但是,我现在正在努力解决的是当我实例化我的类时,如何获得对可以传递给 TestClass 构造函数的 Fluxor Disptacher 的引用?我认为 Fluxor 是作为服务实现的,即;

services.AddFluxor(options =>
{
   options.UseDependencyInjection(typeof(Startup).Assembly)
{);

...这就是它以某种方式在全球范围内可供参考。

下次更新...

我的 TestClass 已更改为实现接口,现在在 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"));
        }
    }

启动.cs

services.AddScoped<ITestClass, TestClass>();

由于这些更改,我期望 TestClass 会被实例化,并且我能够调用它的InitiateAction方法来调度一个动作。但是,它在以下代码中仍然顽固地为空:

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

更新...我的 DeviceListener 类实现了 Cometd.Bayeux.Client.IMessageListener 接口并定义了一个回调,当从服务器进程接收到未经请求的消息时执行该回调。它在 Startup.cs 中被引用:

listener = mClient.getChannel("/v2/me/devices");
listener.subscribe(new GWS.DeviceListener());

该类的结构如下:

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

所有在上面的 DeviceListener 中都有说明,我希望能够从内部调度 Fluxor Action onMessage

上面的 DeviceListener 显示了一个参数化的构造函数,但实际上会导致listener.subscribe(new GWS.DeviceListener());Startup.cs 中的参数编译错误

4

1 回答 1

1

在非组件中使用构造函数注入。

问题可能是您的对象不是由依赖容器创建的,因此没有代码修复 [Inject]

于 2020-07-04T08:45:54.663 回答