eventhandler / action

时间:2015-08-19 06:46:50

标签: c# events interface servicestack eventhandler

上下文: 我正在为我的应用程序使用ServiceStack Framework(4.0.42)。它是自动主存并作为Windows服务运行。主要目的是为某些设备提供通过Web服务(RESTful和ServerEvent)进行通信的能力。

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

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

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

我的问题是我无法弄清楚如何转发RaiseSomeEvent以通知订阅者ServerEvents。 我尝试了很多不同的实现,但都没有。大多数情况下,最终,在运行时,当调用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类:

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#,我处于初级阶段。

非常欢迎任何提示。

1 个答案:

答案 0 :(得分:2)

服务依赖项仅在请求的生命周期内可用,除了释放/处置服务及其依赖项之外。事件并不清楚,它只是在请求期间提出的:

DeviceAdapter.RaiseSomeEvent += DeviceAdapter_RaiseSomeEvent; 

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

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

否则IServerEvents只是ServerEventsFeature Plugin is loaded时注册的普通Singleton依赖项。

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

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

但如果此事件不响应Service请求,那么该事件不应该绑定到Service,即您可以在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可能有用的不同方法。