Using Unity IoC to register and resolve SignalR hubs

廉价感情. 提交于 2019-11-30 19:22:17
Marat Batalandabad

Do it in 3 steps

First. Create UnityHubActivator class

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);
    }
}

Second. Create Unity container and register your dependency resolver before run Startup class

unityContainer = new UnityContainer();
var unityHubActivator = new UnityHubActivator(_unityContainer);
GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => unityHubActivator);
//register some types in container
WebApp.Start<Startup>(startOptions);

Third. Use it in your Hub

public class MyHub : Hub
{
    public MyHub(Logger logger)
    {
        logger.Info("hub constructor");
    }
}

Note. I do not change anything in my Startup class

There's a trick to do that. You will need to do something like this:

container.RegisterType< ChatHub >(new InjectionFactory(CreateChatHub));

......

and then create a private method CreateChatHub

private static object CreateChatHub(IUnityContainer container)
{
    return new ChatHub();
}

1 Create "UnitySignalRDependencyResolver.cs"

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();
    }

    /// <summary>
    /// Gets the Autofac implementation of the dependency resolver.
    /// </summary>
    public static UnitySignalRDependencyResolver Current
    {
        get { return GlobalHost.DependencyResolver as UnitySignalRDependencyResolver; }
    }


    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;
    }
}

2.Add your resolver to Owin pipeline

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
         // Get container
        IUnityContainer container = UnityConfig.Container;

        // Create resolver
        var resolver = new UnitySignalRDependencyResolver(container);

        // Create SignalR Configuration
        var config = new HubConfiguration
        {
            Resolver = resolver
        };
        // Start SignalR
        app.Map("/signalr", map =>
        {
            map.RunSignalR(config);
        });
    }
}

3.Inject your dependency in your controller's constructor

public class ValuesController : ApiController
{
    private readonly IMyDependency _myDependency;

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