通ServiceBase类实例ApiController托管在其上 [英] Pass ServiceBase class instance to ApiController hosted on it

查看:257
本文介绍了通ServiceBase类实例ApiController托管在其上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Windows服务托管与上一个RESTful Web服务。我将与Windows服务throught窗口服务进行通信。

这是我的项目结构:


这是我的类实现。

 命名空间WindowsService_HostAPI
{
    公共部分类SelfHostService:ServiceBase
    {
        私人诠释_value;
        私人HttpSelfHostServer _ SERVER;
        私人静态只读的ILog _log =
            LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod()DeclaringType);        公众诠释的价值
        {
            得到{_value; }
            集合{_value =值; }
        }        公共SelfHostService()
        {
            的InitializeComponent();
        }        保护覆盖无效的OnStart(字串[] args)
        {
            无功配置=新HttpSelfHostConfiguration(HTTP://本地主机:8080);            config.Routes.MapHttpRoute(
                名称:API,
                routeTemplate:{控制器} / {行动} / {ID}
                默认:新{ID = RouteParameter.Optional}
               );            _ SERVER =新HttpSelfHostServer(配置);
            _server.OpenAsync()等待()。
        }        保护覆盖无效调用OnStop()
        {
            如果(_ SERVER!= NULL)
                _server.CloseAsync()等待()。
        }
    }
}

Values​​Controller

 命名空间WindowsService_HostAPI.Controllers
{
    公共类Values​​Controller:ApiController
    {
        [HTTPGET]
        [路线(API /价值/)]
        公众的Htt presponseMessage的GetValue()
        {
            HTT presponseMessage响应= NULL;            返回响应;
        }        [HttpPost]
        [路线(API /价值/ {}值)]
        公众的Htt presponseMessage的SetValue(int值)
        {
            HTT presponseMessage响应= NULL;            返回响应;
        }
    }
}

这只是一个例子,但我需要与Windows服务类通信的ApiController。

我要修改 SelfHostService.Value 属性时,有人做了邮政(方法的SetValue )的设置通过。我该怎么做?


解决方案

  

我需要创建一个类的实例,并保持它活着,直到视窗
  服务停止


做你想要什么用的Web API正确的方法是使用<一个href=\"https://msdn.microsoft.com/en-us/library/system.web.http.dependencies.idependencyresolver%28v=vs.118%29.aspx\"相对=nofollow> 的IDependencyResolver 这里的样品(它使用统一的,但你可以使用任何容器)。

的主要概念是,你建立的依赖,例如合同:

 公共接口IValueProvider
{
    公共int值{搞定;组; }
}

然后实现本合同的地方(你甚至可以实现它 SelfHostService ,但是,实际上,你不应该),配置DI容器使用您的落实,从控制器使用它:

 公共类Values​​Controller:ApiController
{
    私人只读IValueProvider _valueProvider;    公共Values​​Controller(IValueProvider valueProvider)
    {
        _valueProvider = valueProvider;
    }    // code的其余部分在这里
}

请注意,通常DI-容器允许建立父/子层次结构。结果
为了反映这一点,网页API DI方法使用的范围的这个(见 IDependencyResolver.BeginScope 方法)。

有全局作用域和子作用域。在Web API主机创建全局范围启动时。这个范围的生活,直到主机侦听请求。主机创建子范围,收到请求时,与主机需要创建一个控制器做出回应。

DI容器有点不同,当管理对象的生命周期,即用容器中创建的。但共同的是将依赖关系的范围内,在那里他们需要的。所以,如果你想建立一些全球性的依赖,那么你需要将其放置到全球范围。

I'm developing a Windows Service with a RESTFul web service hosted on it. I'm going to communicate with the windows service throught the windows service.

This is my project structure:

These are my classes implementation.

namespace WindowsService_HostAPI
{
    public partial class SelfHostService : ServiceBase
    {
        private int _value;
        private HttpSelfHostServer _server;
        private static readonly ILog _log = 
            LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public int Value
        {
            get { return _value; }
            set { _value = value; }
        }

        public SelfHostService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            var config = new HttpSelfHostConfiguration("http://localhost:8080");

            config.Routes.MapHttpRoute(
                name: "API",
                routeTemplate: "{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
               );

            _server = new HttpSelfHostServer(config);
            _server.OpenAsync().Wait();
        }

        protected override void OnStop()
        {
            if (_server != null)
                _server.CloseAsync().Wait();
        }
    }
}

And ValuesController:

namespace WindowsService_HostAPI.Controllers
{
    public class ValuesController : ApiController
    {
        [HttpGet]
        [Route("api/Value/")]
        public HttpResponseMessage GetValue()
        {
            HttpResponseMessage response = null;



            return response;
        }

        [HttpPost]
        [Route("api/Value/{value}")]
        public HttpResponseMessage SetValue(int value)
        {
            HttpResponseMessage response = null;



            return response;
        }
    }
}

This is only an example, but I need to communicate the ApiController with the Windows Service class.

I have to modify SelfHostService.Value property when someone do a Post (method SetValue) setting value passed. How can I do that?

解决方案

I need to create a class instance and keep it alive until Windows Service stops

The right way to do what you want with Web API is to use IDependencyResolver. Here's the sample (it uses Unity, but you can use any container).

The main concept is that you build up a contract for dependency, e.g.:

public interface IValueProvider
{
    public int Value { get; set; }
}

then implement this contract somewhere (you can even implement it in SelfHostService, but, actually, you shouldn't), configure DI-container to use your implementation, and use it from controller:

public class ValuesController : ApiController
{
    private readonly IValueProvider _valueProvider;

    public ValuesController(IValueProvider valueProvider)
    {
        _valueProvider = valueProvider;
    }

    // the rest of code here
}

Note, that usually DI-containers allow to build parent/child hierarchy.
To reflect this, Web API DI approach uses scopes for this (see IDependencyResolver.BeginScope method).

There are global scope and child scopes. The Web API host creates global scope when it starts. This scope lives until host listens for requests. Host creates child scopes, when request is received, and host needs to create a controller to respond.

DI containers differ a little, when manage lifetime of objects, that were created using container. But the common is to place dependencies to the scope, where they needed. So, if you want to build some "global" dependency, then you need to place it into global scope.

这篇关于通ServiceBase类实例ApiController托管在其上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆