2012-12-13 40 views
1

我想爲使用MEF的SignalR創建一個DependencyResolver。到目前爲止,我有以下幾點:SignalR和MEF

public class SignalRMefDependencyResolver : DefaultDependencyResolver 
{ 
    private readonly CompositionContainer _container; 

    public SignalRMefDependencyResolver(CompositionContainer container) 
    { 
     _container = container; 
    } 

    public override object GetService(Type serviceType) 
    { 
     var export = _container.GetExports(serviceType, null, null).SingleOrDefault(); 

     return null != export ? export.Value : base.GetService(serviceType); 
    } 

    public override IEnumerable<object> GetServices(Type serviceType) 
    { 
     var exports = _container.GetExports(serviceType, null, null); 
     var createdObjects = new List<object>(); 

     if (exports.Any()) 
     { 
      createdObjects.Concat(exports.Select(x => x.Value)); 
     } 

     createdObjects.Concat(base.GetServices(serviceType)); 
     return createdObjects; 
    } 
} 

我覺得GetService的是工作,但GetServices未能找到IHubDescriptorProvider和IMethodDescriptorProvider出口 - 無論是在MEF或基地。

在我的Application_Start我有以下爲發生第二件事 - 第一個是創建MEF容器:

 RouteTable.Routes.MapHubs(new SignalRMefDependencyResolver(MefConfig.Container)); 

我也試過:

  GlobalHost.DependencyResolver = new SignalRMefDependencyResolver(MefConfig.Container); 
     RouteTable.Routes.MapHubs(); 

與同結果。

我在這裏錯過了一些明顯的東西嗎?我發現的所有樣品都用於其他容器,看起來更復雜。

感謝

+0

你怎麼知道它不工作?它如何失敗? – Pete

+0

合乎邏輯的問題:)當我遍歷解析器時,它將爲這兩個接口返回null。另外,當我嘗試從客戶端啓動集線器時,我的集線器未被創建。 – Jonesie

+0

您確定這些對象在您的MEF容器中嗎?什麼是你的MEF設置? (你有什麼設置[導入]和[導出]的東西?) – Pete

回答

2

看起來像這裏的問題是你使用「CONCAT()」 - 它返回一個新的集合,而不是改變它呼籲集合。

1

Linq-to-objects操作符(Concat就是其中之一)是無副作用的,這意味着當你做createdObjects.Concat(exports.Select(x => x.Value));時,連接不會發生在createdObjects上,而會發生在你決定枚舉Concat的結果。它幾乎是所有返回IEnumerable<T>的其他Linq運營商的延期運營商。看看classification of Standard Query Operators by manner of execution

現在爲您的代碼的工作,請嘗試以下操作:

public override IEnumerable<object> GetServices(Type serviceType) 
{ 
    var mefExports = _container.GetExports(serviceType, null, null); 

    //We need this because 
    var dependencyResolverServices = base.GetServices(serviceType); 
    if (dependencyResolverServices == null) 
    { 
     dependencyResolverServices = Enumerable.Empty<object>(); 
    } 

    return mefExports.Select(x => x.Value).Concat(dependencyResolverServices); 
} 

您需要檢查的base.GetServices的返回值,因爲DefaultDependencyResolver'sGetServices可以返回null。

然後你所要做的就是列舉你的GetServices的結果。