1

我正在尝试使用 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 无法找到 IHubDescriptorProvider 和 IMethodDescriptorProvider 的导出 - 无论是在 MEF 中还是在基础中。

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

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

我也试过:

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

结果相同。

我在这里遗漏了一些明显的东西吗?我发现的所有样本都是针对其他容器的,而且看起来要复杂得多。

谢谢

4

2 回答 2

2

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

于 2012-12-19T07:30:16.263 回答
1

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

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

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

于 2012-12-19T09:00:36.253 回答