SignalR +依赖注入问题 [英] SignalR + Dependency Injection Questions

查看:187
本文介绍了SignalR +依赖注入问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我MVC3应用程序中使用SignalR,因为我已经实现了我的控制器StructureMap依赖注入,我想这样做在我的枢纽,但我似乎无法得到它的工作。

I am using SignalR in my MVC3 application, and since I have implemented StructureMap Dependency Injection on my controllers I would like to do the same in my hub, but I can't seem to get it working.

请告诉我有什么错我的codeS如下:

Please tell me what's wrong with my codes below:

SignalRSmDependencyResolver.cs

public class SignalRSmDependencyResolver : DefaultDependencyResolver
{
    private IContainer _container;

    public SignalRSmDependencyResolver(IContainer container)
    {
        _container = container;
    }

    public override object GetService(Type serviceType)
    {
        object service = null;
        if (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
        {
            // Concrete type resolution
            service = _container.GetInstance(serviceType);
        }
        else
        {
            // Other type resolution with base fallback
            service = _container.TryGetInstance(serviceType) ?? base.GetService(serviceType);
        }
        return service;
    }

    public override IEnumerable<object> GetServices(Type serviceType)
    {
        var objects = _container.GetAllInstances(serviceType).Cast<object>();
        objects.Concat(base.GetServices(serviceType));
        return objects;
    }
}

SignalRExtensionsRegistry.cs

public class SignalRExtensionsRegistry : Registry
{
    public SignalRExtensionsRegistry()
    {
        For<IDependencyResolver>().Add<SignalRSmDependencyResolver>();
    }
}

IoC.cs

public static class IoC {
    public static IContainer Initialize() {

        var container = BootStrapper.Initialize();

        container.Configure(x =>
        {
            x.For<IControllerActivator>().Singleton().Use<StructureMapControllerActivator>();
        });

        return container;
    }
}

public class StructureMapControllerActivator : IControllerActivator {
    public StructureMapControllerActivator(IContainer container) {
        _container = container;
    }

    private IContainer _container;

    public IController Create(RequestContext requestContext, Type controllerType) {
        IController controller = DependencyResolver.Current.GetService(controllerType) as IController;
        return controller;
    }
}

AppStart_Structuremap.cs

[assembly: WebActivator.PreApplicationStartMethod(typeof(StoreUI.AppStart_Structuremap), "Start")]

namespace MyNameSpace {
public static class AppStart_Structuremap {
    public static void Start() {
        var container = (IContainer) IoC.Initialize();
        DependencyResolver.SetResolver(new StructureMapDependenceyResolver(container));
        AspNetHost.SetResolver(new StructureMapDependencyResolver(container));            
    }
}
}

NotificationsHub.cs

[HubName("notificationsHub")]
public class NotificationsHub : Hub
{    
    #region Declarations
    private readonly IUserService userService;
    #endregion

    #region Constructor

    public NotificationsHub(IUserService userService)
    {
        this.userService = userService;
    }

    #endregion

    public void updateServer(string message)
    {
        Clients.updateClient(message);
    }
}

感谢

推荐答案

获取Structuremap到SignalR实际上是pretty容易。首先你要创建自己的解析器:

Getting Structuremap into SignalR is actually pretty easy. First you want to create your own resolver:

Usings:

using SignalR.Infrastructure;
using StructureMap;

类:

public class StructureMapResolver : DefaultDependencyResolver
{
    private IContainer _container;

    public StructureMapResolver(IContainer container)
    {
        _container = container;
    }

    public override object GetService(Type serviceType)
    {
        object service = null;
        if (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
        {
            // Concrete type resolution
            service = _container.GetInstance(serviceType);
        }
        else
        {
            // Other type resolution with base fallback
            service = _container.TryGetInstance(serviceType) ?? base.GetService(serviceType);
        }
        return service;
    }

    public override IEnumerable<object> GetServices(Type serviceType)
    {
        var objects = _container.GetAllInstances(serviceType).Cast<object>();
        return objects.Concat(base.GetServices(serviceType));
    }
}

这里的想法是尝试和使用的容器来解决依赖关系,如果你没有依赖接线,通过它传递给默认的解析器。这样,您就不必担心其他所有依赖于SignalR,只能专注于你希望注入(集线器,ConnectionIdFactory,MessageBus等)的东西。

The idea here is to try and use your container to resolve the dependencies, if you do not have the dependency wired up, pass it through to the default resolver. This way you don't have to worry about all of the other dependencies in SignalR and can focus only on the stuff you want to inject into (Hubs, ConnectionIdFactory, MessageBus, etc.).

接下来你将要在容器中注册这个(我喜欢使用登记):

Next you will want to register this in your container (i like using registries):

Usings:

using SignalR.Infrastructure;
using StructureMap.Configuration.DSL;

类:

public class ExtensionsRegistry : Registry
{
    public ExtensionsRegistry()
    {
        For<IDependencyResolver>().Add<StructureMapResolver>();
    }
}

解析器替换

最后,你会想告诉SignalR使用您的解析器,而不是默认的:

Resolver Replacement

Finally you will want to tell SignalR to use your resolver instead of the default:

全球::或的Application_Start :: WebActivator pre_START

Usings:

using SignalR.Hosting.AspNet;
using SignalR.Infrastructure;

的Application_Start:

// Make sure you build up the container first
AspNetHost.SetResolver(StructureMap.ObjectFactory.GetInstance<IDependencyResolver>());

傻集线器注射依赖

现在你可以注入你的容器知道任何有关依赖到集线器本身:

Silly Hub with injected dependencies

Now you can just inject any dependencies your container knows about into the hubs themselves:

[HubName("defaultHub")]
public class DefaultHub : Hub, IDisconnect
{
    private readonly IRepository _repo;
    public DefaultHub(IRepository repo)
    {
        _repo = repo;
    }

    public void Connect()
    {
        Caller.setUser(Context.ConnectionId);
        Clients.addMessage(string.Format("{0} has connected", Context.ConnectionId));
    }

    public void MessageSender(string message)
    {
        Caller.addMessage(_repo.RepositoryMessage());
        Clients.addMessage(message);
    }

    public Task Disconnect()
    {
        var clientId = this.Context.ConnectionId;
        return Task.Factory.StartNew(() => { Clients.addMessage(string.Format("{0} has disconnected", clientId)); });
    }
}

这篇关于SignalR +依赖注入问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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