Asp.net-Mvc-3

SignalR + 依賴注入問題

  • March 20, 2012

我在我的 MVC3 應用程序中使用 SignalR,並且由於我已經在我的控制器上實現了 StructureMap 依賴注入,我想在我的集線器中做同樣的事情,但我似乎無法讓它工作。

請告訴我下面的程式碼有什麼問題:

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

國際奧委會

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 實際上非常容易。首先,您要創建自己的解析器:

StructureMap 解析器

用途:

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 中的所有其他依賴項,並且可以只關注您想要注入的內容(Hubs、ConnectionIdFactory、MessageBus 等)。

解析器和集線器的綁定

接下來,您將要在您的容器中註冊它(我喜歡使用系統資料庫):

用途:

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

班級:

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

解決更換

最後,您將要告訴 SignalR 使用您的解析器而不是預設值:

Global::Application_Start 或 WebActivator::Pre_Start

用途:

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

應用程序_開始:

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

具有註入依賴項的愚蠢集線器

現在您可以將您的容器知道的任何依賴項注入集線器本身:

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

引用自:https://stackoverflow.com/questions/9790433