Pass ServiceBase class instance to ApiController hosted on it

亡梦爱人 提交于 2019-12-12 00:32:44

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/32374489/pass-servicebase-class-instance-to-apicontroller-hosted-on-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!