SignalR和MEF

时间:2012-12-13 19:06:52

标签: mef signalr

我正在尝试使用MEF为SignalR创建DependencyResolver。到目前为止,我有以下内容:

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无法在MEF或基础中找到IHubDescriptorProvider和IMethodDescriptorProvider的导出。

在我的Application_Start中,我有以下第二件事 - 第一件事是创建MEF容器:

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

我也试过了:

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

具有相同的结果。

我错过了一些明显的东西吗?我发现的所有样品都是针对其他容器的,看起来要复杂得多。

由于

2 个答案:

答案 0 :(得分:2)

看起来这里的问题是你使用'Concat()' - 它返回一个新的集合,而不是改变它被调用的集合。

答案 1 :(得分: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's GetServices可以返回null。

然后,您只需枚举GetServices的结果。