eventhandler/action 触发的服务堆栈服务器事件

servicestack serverevents triggered by eventhandler/action

上下文: 我正在为我的应用程序使用 ServiceStack Framework (4.0.42)。它是自托管的,并作为 windows 服务运行。主要目的是让一些设备能够通过网络服务(RESTful 和 ServerEvent)进行通信。

为此,我为所有类型的设备创建了一个通用接口,如下所示(简化):

public interface IDevice
{
    string GetName();        
    bool IsConnected(string id);
    event EventHandler<EventArgs> RaiseSomeEvent;
}

此接口在 DLL 中针对每种类型的设备实现。

我的问题是我不知道如何转发 RaiseSomeEvent 以通知订阅者到 ServerEvents。 我尝试了许多不同的实现,其中 none 有效。最后,大多数情况下,在运行时,当 DeviceAdapter_RaiseSomeEvent 被调用时,ServerEvents 实例为空。

我现在 运行 没主意了。

这是实际(简化)版本:

public class ServiceInterface : Service
{
    public IDevice DeviceAdapter { get; set; }         
    public IServerEvents ServerEvents { get; set; }
    public IAppSettings AppSettings { get; set; }

    public ServiceInterface(IDevice deviceAdapter)
    {
        DeviceAdapter = deviceAdapter;
        DeviceAdapter.RaiseSomeEvent += DeviceAdapter_RaiseSomeEvent;       
    }

    public void DeviceAdapter_RaiseSomeEvent(object sender, EventArgs e)
    {
        ServerEvents.NotifyAll("Something happend!");            
    }

这里是 AppHost Class:

public class AppHost : AppSelfHostBase
{
    public IDevice DeviceAdapter;

    public AppHost()
        : base("grob.MachineConnector.Service", typeof(ServiceInterface).Assembly)
    { }

    public override void Configure(Funq.Container container)
    {            
        this.Plugins.Add(new ServerEventsFeature());

        switch (UsedAdapter)
        {
            case enAdapterTyp.DeviceTyp1:
                DeviceAdapter = new DeviceTyp1();
                break;
            case enAdapterTyp.DeviceTyp2:
                DeviceAdapter = new DeviceTyp2();

                break;
            default:
                throw new AdapterTypException("Wrong or no Adaptertyp is configured:" + UsedAdapter.ToString());
        }            
        container.Register(new ServiceInterface(DeviceAdapter));                       
    }       

也许它在 Funq 的某个地方。我不确定 DI、IoC、自动装配到底发生了什么。我试图为框架编写自己的插件。当我的设备发生事件时,我不知道如何获取 IServerEvents 的有效实例。 也许我犯了一些一般的设计错误。对于 OOP 和 C#,我处于初级水平。

非常欢迎任何提示。

服务依赖项仅在请求的生命周期内可用,超过该服务及其依赖项是 released/disposed。从事件中不清楚它仅在请求期间引发:

DeviceAdapter.RaiseSomeEvent += DeviceAdapter_RaiseSomeEvent; 

您也不应注册服务,因为它们会由 ServiceStack 自动注册和自动装配:

 //Don't register Services
 //container.Register(new ServiceInterface(DeviceAdapter));         

否则 IServerEvents 只是在 ServerEventsFeature Plugin is loaded.

时注册的普通单例依赖项

通常你会像访问任何其他依赖项一样访问它,你只需在需要它的依赖项中解析它,即:

container.Register<IDevice>(c => new DeviceTyp1 { 
    ServerEvents = c.Resolve<IServerEvents>()
});

这会自动将解析的 IDevice 注入到服务依赖项中:

public class ServiceInterface : Service
{
    public IDevice DeviceAdapter { get; set; }         

    public object Any(Request request)
    {
        //DeviceAdapter also has access to IServerEvents
        DeviceAdapter.Exec(request); 
    }
}

但如果此事件不是对服务请求的反应,则不应将该事件绑定到服务,即您可以只在 AppHost 中拥有处理程序:

public override void Configure(Funq.Container container)
{            
    DeviceAdapter.RaiseSomeEvent += DeviceAdapter_RaiseSomeEvent;       
}

public void DeviceAdapter_RaiseSomeEvent(object sender, EventArgs e)
{
    var serverEvents = Container.Resolve<IServerEvents>();
    serverEvents.NotifyAll("cmd.Handler", "Something happend!");            
}

另请参阅 documentation on Selectors,以便您了解应使用哪个选择器发送消息。

以不同的方式查看此答案resolve IOC dependencies from outside of ServiceStack可能也会有所帮助。