Как внедриться в концентратор SignalR из-за пределов контейнера веб-приложения

#asp.net-core #dependency-injection #asp.net-core-signalr

Вопрос:

У меня есть приложение, которое управляет физическим устройством в режиме реального времени, и я хотел бы разрешить выполнение управляющих действий также в ответ на запросы удаленных клиентов. Я хотел бы использовать SignalR в качестве протокола реального времени для этого, и поэтому у меня есть веб-компонент с автономным хостингом, который предоставляет сервер SignalR. Я хотел бы внедрить объект, созданный вне веб-узла, в свой класс-концентратор, чтобы он мог управлять входящими сообщениями и выполнять командные действия в другом месте приложения.

Внедрение зависимостей в Asp .Net Core

Приведенная выше ссылка описывает внедрение зависимостей, однако это относится только к объектам, созданным в контейнере веб-хоста. Я хотел бы внедрить объект извне веб-хоста.

Я могу ввести объект MyController в MyHub из класса запуска, как показано в приведенном ниже коде.

 public class MyController : IMyController
{
    public Command(string message)
    {
        // .....
    }

}

public class MyHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
        ProcessMessage(user, message);

    }
    public MyHub(IMyController myController)
    {
        _myController = myController;
    }

    void ProcessMessage(string name, string message)
    {
        // ...
        // ...
        // ...
        _myController.Command(message);
        // ...
        // ...
        // ...
    }
    readonly IMyController _myController;
}

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSignalR();
        services.AddSingleton<IMyController, MyController>();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHub<MyHub>("/myHub");
        });
    }
}
 

Веб-узел SignalR создается из моего приложения следующим образом.

 public static void Start()
{
    CreateHostBuilder().Build().Run();
}

public static IHostBuilder CreateHostBuilder() =>
    Host.CreateDefaultBuilder()
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
            webBuilder.UseUrls("http://localhost:2803");
        });
 

Я был бы признателен, если бы кто-нибудь мог посоветовать, как внедрить объект MyController, созданный вне класса запуска, в экземпляр MyHub.

Я понимаю, что HubContext можно использовать для отправки сообщений клиентам из-за пределов компонента веб-приложения, но я бы, по сути, хотел получать сообщения от клиентов и выполнять действия за пределами веб-узла.

Комментарии:

1. Пожалуйста, поясните, что вы имеете в виду «за пределами веб-приложения»?

2. Возможно, это неверная фраза. Веб-хостинг был бы более подходящим. Мое приложение работает на веб-узле и выполняет действия за пределами веб-узла. Веб-узел используется для создания сервера signal R для приема командных действий от клиентов. Пожалуйста, дайте мне знать, если это все еще не ясно.

3. Если вы хотите использовать MyHub внутри MyController, просто создайте новый экземпляр HubConnectionBuilder и подключитесь к SignalR внутри своего контроллера. Там есть . Сетевой клиент доступен для кода на стороне сервера

4. Неясно, есть ли у вас 2 приложения, веб-приложение и какое-либо другое приложение, или вы ссылаетесь на разные части своего веб-приложения как на веб-хост и что-то еще. Возможно, вы сможете показать код «внешней» вещи.

5. Извините, я новичок в этом деле. Я обновил свое описание. Существует одно приложение, которое выполняет множество функций управления устройствами и имеет свой собственный IOC. Внутри этого приложения находится сервер SignalR, созданный в рамках самостоятельного веб-компонента. Я новичок в этом, поэтому не знаю правильной терминологии. Пожалуйста, дайте мне знать, если это не ясно. Спасибо.