How to Inject dependencies in a Unity IoC container for SignalR hub?

折月煮酒 提交于 2021-01-27 14:41:55

问题


I have an application that is written with c# on the top of the ASP.NET MVC 5 Framework. I implemented Unity.Mvc into my project. Now, I am trying to inject dependencies objects into my SignalR Hub.

I created a class called UnityHubActivator

My class looks like this

public class UnityHubActivator : IHubActivator
{
    private readonly IUnityContainer _container;

    public UnityHubActivator(IUnityContainer container)
    {
        _container = container;
    }

    public IHub Create(HubDescriptor descriptor)
    {
        return (IHub)_container.Resolve(descriptor.HubType);
    }
}

Then in my UnityConfig class I added the following to my RegisterTypes method

var unityHubActivator = new UnityHubActivator(container);

container.RegisterInstance<IHubActivator>(unityHubActivator);

My hub looks like this

[Authorize]
public class ChatHub : Hub
{
    protected IUnitOfWork UnitOfWork { get; set; }

    public ChatHub(IUnitOfWork unitOfWork)
        : base()
    {
        UnitOfWork = unitOfWork;
    }

}

But when I run the hub, the constructor never get called and the connection never takes place.

How can I correctly use Unity framework to inject dependencies into my hub?

UPDATED

I tried to created a custom container like so

public class UnitySignalRDependencyResolver: DefaultDependencyResolver
{
    protected IUnityContainer Container;
    private bool IsDisposed = false;

    public UnitySignalRDependencyResolver(IUnityContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }

        Container = container.CreateChildContainer();
    }

    public override object GetService(Type serviceType)
    {
        if (Container.IsRegistered(serviceType))
        {
            return Container.Resolve(serviceType);
        }

        return base.GetService(serviceType);
    }

    public override IEnumerable<object> GetServices(Type serviceType)
    {
        if (Container.IsRegistered(serviceType))
        {
            return Container.ResolveAll(serviceType);
        }

        return base.GetServices(serviceType);
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);

        if(IsDisposed)
        {
            return;
        }

        if(disposing)
        {
            Container.Dispose();
        }

        IsDisposed = true;
    }
} 

Then here is how I configured the hub in the Startup class

public class Startup
{
    public IUnityContainer Container { get; set; }
    public Startup(IUnityContainer container)
    {
        Container = container;
    }

    public void Configuration(IAppBuilder app)
    {
        app.Map("/signalr", map =>
        {
            var resolver = new UnitySignalRDependencyResolver(Container);

            var hubConfiguration = new HubConfiguration
            {
                Resolver = resolver
            };

            map.RunSignalR(hubConfiguration);
        });
    }
}

But still now working... the hub constructor never get called.

Here is how I am calling my hub from the client

<script src="~/Scripts/jquery.signalR-2.2.2.min.js"></script>
<script src="~/signalr/hubs"></script>
<script>

$(function () {
    // Reference the auto-generated proxy for the hub.
    var app = $.connection.chatHub;
    console.log('Getting things ready....');

    app.client.outOfTasks = function () {
        console.log('Nothing to do here')
    };

    app.client.logError = function (message) {
        console.log(message)
    };

    app.client.logNote = function (message) {
        console.log(message)
    };

    app.client.assignTask = function (taskId) {
        app.server.taskReceived();
        console.log('task received!!!' + taskId);

    };

    // Start the connection.
    $.connection.hub.start().done(function () {
        console.log('Connection Started....');
    });
});

</script>

回答1:


The UnitySignalRDependencyResolver appears accurate for that container.

Taken from the official documentation,

Dependency Injection in SignalR

try the following example for configuring Startup

public class Startup{    
    public void Configuration(IAppBuilder app) {
        IUnityContainer container = GetContainer(); 

        var resolver = new UnitySignalRDependencyResolver(container);

        var config = new HubConfiguration {
            Resolver = resolver
        };      
        app.MapSignalR("/signalr", config);
    }

    IUnityContainer GetContainer() {
        //...call the unity config related code.
        var container = UnityConfig.Container;
        //...any other code to populate container.

        return container;
    }
}

Make sure to register the necessary objects, including the hub (ChatHub) with the container as the container needs to know the object graph in order to resolve the necessary dependencies.



来源:https://stackoverflow.com/questions/49019889/how-to-inject-dependencies-in-a-unity-ioc-container-for-signalr-hub

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