上下文: 我正在为我的应用程序使用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#,我处于初级阶段。
非常欢迎任何提示。
答案 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可能有用的不同方法。