gpt4 book ai didi

c# - 将 ASP.Net OWIN 引入现有的 TopShelf Windows 服务

转载 作者:太空宇宙 更新时间:2023-11-03 15:44:48 24 4
gpt4 key购买 nike

我有一个现有的 Windows 服务,它可以启动、读取一些配置、启动一些线程并执行一些有用的工作。目前我将该工作(通过 TopShelf.Log4Net/Log4Net)记录到磁盘(或控制台)。

我在想公开一个 API 以允许人们查询服务会很好(将来甚至可能动态配置它)

不过,我很难找到一种合适的方法将两者结合起来。我现有的 Windows 服务有一堆工作线程,它知道正在完成的工作的上下文、统计信息和进度等等。

但是在实际处理请求的 ApiController 上下文中,我看不到获取这些统计信息的明显/简单方法。我尝试在我的 Startup 类中的 IAppBuilder 的属性中传递一些对象引用,但任何时候我自己明确地进行配置时,我似乎都会丢失我拥有的默认 MVC 路由。

有人对将 OWIN 集成到现有服务中/在现有服务之上有任何建议吗?

编辑:添加代码:

所以我有一个非常基本的 TopShelf 转轮;

        HostFactory.Run(x =>
{
x.Service<MyService>(s =>
{
s.ConstructUsing(name => new MyService());
s.WhenStarted(lb => lb.Start());
s.WhenStopped(lb => lb.Stop());
});
x.RunAsLocalSystem();

在 MyService 中,我有一个 StartWorkers() 方法,该方法会启动,启动一堆 worker,并跟踪它们。

public class MyService
{
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

private List<Worker> workers { get; set; }
private List<Thread> _threads { get; set; }

public MyService()
{
StartWorkers();
}

现在,我希望能够从 API 请求中查询这些工作人员的状态,所以我想我可以做类似的事情;

public class MyService
{
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

private List<Worker> workers { get; set; }
private List<Thread> _threads { get; set; }
private IDisposable _webServer { get; set; }

public MyService()
{
StartWorkers();
StartWebServer();
}

private void StartWebServer()
{
const string baseAddress = "http://localhost:10281/";
_webServer = WebApp.Start<Startup>(url: baseAddress);
log.DebugFormat("Loaded webserver at address={0}", baseAddress);
}

现在所有的 OWIN 代码都是样本中的普通代码。当我测试这段代码时,我可以点击由 ValuesController 提供的/api/values 示例端点,一切正常。

现在我遗漏了一 block 胶水是如何从我的 Controller 访问我的应用程序中有用的任何东西。我可以做一些天真的事情,比如将 Worker 列表设为 public static;

public class MyService
{
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

public static List<Worker> workers { get; set; }

在这种情况下,我可以通过我的 Controller 执行类似的操作;

public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
// nonsense/test code
return MyService.workers.Select(i => i.ErrorsEncountered.ToString()).ToArray();
}

必须有一种更好的方法来访问我的应用程序的内部结构而无需操作可见性。我所看到的是,在使用 WebApp.Start() 时,我可以将对象传递到 IAppBuilder 的属性中。这些在路由配置中是可见的,我看到能够从我的 ApiController 中访问它们,例如;

public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
var someWorker = base.ControllerContext.Configuration.Properties["someWorkerReference"];

当我沿着这条路走下去时,我遇到的问题是“WebApp.Start(url: baseAddress);”可以正常工作并且我的路由都可以正常工作,但是使用 WebApp.Start() 方法并传入一个 Action 会导致我的路由中断

所以我不想花时间修复路由,而是想看看是否有一种明显的/已知的/官方的方法将“上下文”传递到 Web 服务器

最佳答案

所以这就是容器非常有用的地方。如果您有类似 public class MyService : IStatusProvider {} 的东西,那么您可以将 MyServiceIStatusProvider 注册到同一个实例。 How to use DI container when OwinStartup谈论使用 OWIN 和依赖注入(inject)。您可以将容器设置添加到程序的开头,将 s.ConstructUsing(name => new MyService()); 更改为

s.ConstructUsing(name => {
var container = new Container();
// container setup
return container.resolve<MyService>(); // method depends on your container
});

关于c# - 将 ASP.Net OWIN 引入现有的 TopShelf Windows 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28582300/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com