SignalR and MEF



我正在尝试使用 MEF 为 SignalR 创建一个依赖解析器。 到目前为止,我有以下内容:

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 中还是在 base 中。

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

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

我也试过:

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

结果相同。

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

谢谢

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

Linq-to-objects运算符(Concat是其中之一)是无副作用的,这意味着当您执行createdObjects.Concat(exports.Select(x => x.Value));时,连接不会在createdObjects上进行,而是在您决定枚举Concat的结果时发生。它是一个延迟运算符,因为几乎所有其他返回 IEnumerable<T> 的 Linq 运算符。按执行方式查看标准查询运算符的分类。

现在,要使代码正常工作,请尝试以下操作:

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 的GetServices可以返回 null。

然后你所要做的就是枚举你的GetServices的结果。

最新更新