2013-04-22 58 views
4

我试图让signalR hub作为使用MEF的插件的一部分。但是,在调用ImportMany对象列表后,然后在Global.asax文件的Application_Start()方法中添加目录/容器/ ComposeParts部分后,我得到的全部是:使用MEF加载插件后映射SignalR Hub

未捕获的TypeError:无法读取属性'server '未定义。

如果问题来自我的界面,插件,global.asax文件或javascript,我不知道。

接口:

public interface IPlugin 
{ 

} 

插件:

[Export(typeof(IPlugin))] 
[HubName("testHub")] 
public class TestHub : Hub, IPlugin 
{ 
    public string Message() 
    { 
     return "Hello World!"; 
    } 
} 
在Global.asax文件

[ImportMany(typeof (IPlugin))] 
    private IEnumerable<IPlugin> _plugins { get; set; } 

    protected void Application_Start() 
    { 
     var catalog = new AggregateCatalog(); 
     catalog.Catalogs.Add(new DirectoryCatalog(@"./Plugins")); 
     var container = new CompositionContainer(catalog); 
     container.ComposeParts(this); 

     RouteTable.Routes.MapHubs(); 

     //log4net 
     log4net.Config.XmlConfigurator.Configure(); 

     AreaRegistration.RegisterAllAreas(); 
     WebApiConfig.Register(GlobalConfiguration.Configuration); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 
    } 

最后的JavaScript:

$(document).ready(function() { 
     $.connection.hub.url = 'http://127.0.0.1/signalr/'; 
     var proxy = $.connection.testHub; 
     $.connection.hub.start({ transport: ['webSockets', 'serverSentEvents', 'longPolling'] }) 
        .done(function() { 
         proxy.invoke('Message').done(function(res) { 
          alert(res); 
         }); 
        }) 
        .fail(function() { alert("Could not Connect!"); }); 
    }); 

我发现的唯一信息是this post,但我无法使其工作。当我手动添加参考时,一切工作正常,但是当我在加载插件后查看“signalr/hubs”时,则没有提及我的集线器方法。

非常感谢您的帮助。

+0

我不确定你在做什么是有道理的。你无法用Hub实例做任何事情。你不拥有它们的创建,并且你不能从服务器调用它们,所以我没有把它们作为MEF输出的重点。 你在找DI吗? – davidfowl 2013-04-22 09:45:55

+0

假设你有Hub1的Project1和Hub2的project2。当你添加引用Project1和Project2从说你的主MVC项目,然后调用RouteTable.Routes.MapHubs();在global.asax中,你可以在你的javascript中调用hub1和hub 2的所有方法。我试图找到以编程方式执行该操作的最佳方式,即动态加载包括集线器在内的dll到我的主应用程序中。 – lool 2013-04-22 11:19:04

+0

我很新的插件框架/ DI,所以毫无疑问,我可能会困惑自己 – lool 2013-04-22 11:28:40

回答

3

您的问题是SignalR caches the generated "signalr/hubs" proxy script第一次被请求。 SignalR提供缓存的脚本来响应每个后续对“signalr/hubs”的请求。

SignalR不仅会缓存脚本本身,还会在流程开始时找到它caches the collection of Hubs

您可以解决缓存的代理脚本问题by simply not using the proxy script,但仍然无法实际连接到在进程启动后加载的程序集中定义的集线器。

如果您希望能够连接到这样的集线器,则需要实现您自己的IHubDescriptorProvider,以了解在运行时加载的插件中定义的集线器。

你可以注册SignalR的DependencyResolver它可以通过你传递到MapSignalRHubConfiguration对象的Resolver特性传递到SignalR提供商。

也就是说,无论何时将插件添加到“./Plugins”目录中,重新启动应用程序池/服务器进程可能会更容易。

+0

非常感谢您的指示。其实我找到了另一个解决方案。我很困惑,因为ReflectedHubDescriptorProvider实际上正在返回新的集线器,但我无法联系它。我开始讨论这个项目:[https://github.com/cjbhaines/SignalRProxyGenerator](https://github.com/cjbhaines/SignalRProxyGenerator),这对我有很大的帮助。我创建了自己的hubs.js文件,并引用它而不是signalr/hubs。现在运作良好! – lool 2014-04-25 13:54:17