ASP.NET MVC2和MEF - 为什么我的MefControllerFactory不能获得导出或MetaData?

时间:2011-02-14 20:05:44

标签: c# asp.net asp.net-mvc asp.net-mvc-2 mef

我正在关注此博客文章:http://blog.maartenballiauw.be/post/2009/04/21/ASPNET-MVC-and-the-Managed-Extensibility-Framework-%28MEF%29.aspx我正在实施MefControllerFactory

MefControllerFactory Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Web.Mvc;

namespace plugme.Utilities
{

    public class MefControllerFactory : IControllerFactory
    {
        private string pluginPath;
        private DirectoryCatalog catalog;
        private CompositionContainer container;

        private DefaultControllerFactory defaultControllerFactory;

        public MefControllerFactory(string pluginPath)
        {
            this.pluginPath = pluginPath;
            this.catalog = new DirectoryCatalog(pluginPath);
            this.container = new CompositionContainer(catalog);

            this.defaultControllerFactory = new DefaultControllerFactory();
        }

        #region IControllerFactory Members

        public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            IController controller = null;

            if (controllerName != null)
            {
                string controllerClassName = controllerName + "Controller";

                // "Export" isn't recognized
                // and "Metadata" (as in c => c.Metadata ) isn't recognized.
                Export<IController> export = this.container.GetExports<IController>()
                                                 .Where(c => c.Metadata.ContainsKey("controllerName")
                                                     && c.Metadata["controllerName"].ToString() == controllerName)
                                                 .FirstOrDefault();
                if (export != null)
                {
                    controller = export.GetExportedObject();
                }
            }

            if (controller == null)
            {
                return this.defaultControllerFactory.CreateController(requestContext, controllerName);
            }

            return controller;
        }

        public void ReleaseController(IController controller)
        {
            IDisposable disposable = controller as IDisposable;
            if (disposable != null)
            {
                disposable.Dispose();
            }
        }

        #endregion
    }
}

我得到的错误是:

Error 1 The type or namespace name 'Export' could not be found 
        (are you missing a using directive or an assembly reference?)   

Error 2 'System.Lazy<System.Web.Mvc.IController>' does not contain a 
        definition for 'Metadata' and no extension method 'Metadata' 
        accepting a first argument of type 
        'System.Lazy<System.Web.Mvc.IController>' could be found 
        (are you missing a using directive or an assembly reference?)

Error 3 'System.Lazy<System.Web.Mvc.IController>' does not contain a 
        definition for 'Metadata' and no extension method 'Metadata' 
        accepting a first argument of type 
        'System.Lazy<System.Web.Mvc.IController>' could be found 
        (are you missing a using directive or an assembly reference?)   

我很困惑为什么这不会识别ExportMetadata。你们有什么想法吗?

修改

我换了一行:

 Export<IController> export = this.container.GetExports<IController>()
                                                 .Where(c => c.Metadata.ContainsKey("controllerName")
                                                     && c.Metadata["controllerName"].ToString() == controllerName)
                                                 .FirstOrDefault();

要:

var export = this.container.GetExports<IController>()
                                                 .Where(c => c.Metadata.ContainsKey("controllerName")
                                                     && c.Metadata["controllerName"].ToString() == controllerName)
                                                 .FirstOrDefault();

Metadata处理我的问题。但是现在我用下一个if语句引发了一个新的错误:

            if (export != null)
            {
                controller = export.GetExportedObject(); 
            }

错误:

 'System.Lazy<System.Web.Mvc.IController,System.Collections.Generic.IDictionary<string,object>>' does not contain a definition for 'GetExportedObject' and no extension method 'GetExportedObject' accepting a first argument of type 'System.Lazy<System.Web.Mvc.IController,System.Collections.Generic.IDictionary<string,object>>' could be found (are you missing a using directive or an assembly reference?)

2 个答案:

答案 0 :(得分:5)

该博文基于MEF的预览版。 API在最终版本发布之前已更改,您应使用export.Value代替export.GetExportedObject()

答案 1 :(得分:5)

你也可以使用:

Lazy<IController> export = this.container.GetExports<IController, IDictionary<string, object>>()
    .Where(c => c.Metadata.ContainsKey("ControllerName")
        && c.Metadata["ControllerName"].ToString().ToLowerInvariant().Equals(controllerName.ToLowerInvariant())).
            FirstOrDefault();

另外,您需要实现IControllerFactory函数=&gt;

public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            return SessionStateBehavior.Default;
        }

new export
icontrollerfactory-implementation