0

以下是我遇到的症状:

我在一个区域有一个全新的空控制器:

public class JamController : Controller
{
    public JamController()
    {
        throw new Exception("Not implemented!");
    }

如果我访问http://myprojectserver.example.com:12345/urlthatdoesnotexist,我会收到以下错误:

[CompositionException: The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) Not implemented!

Resulting in: An exception occurred while trying to create an instance of type 'MyWebProject.Areas.Users.Controllers.JamController'.

Resulting in: Cannot activate part 'MyWebProject.Areas.Users.Controllers.JamController'.
Element: MyWebProject.Areas.Users.Controllers.JamController -->  MyWebProject.Areas.Users.Controllers.JamController

Resulting in: Cannot get export 'MyWebProject.Areas.Users.Controllers.JamController (ContractName="System.Web.Mvc.IController")' from part 'MyWebProject.Areas.Users.Controllers.JamController'.
Element: MyWebProject.Areas.Users.Controllers.JamController (ContractName="System.Web.Mvc.IController")
]
   System.ComponentModel.Composition.Hosting.CompositionServices.GetExportedValueFromComposedPart(ImportEngine engine, ComposablePart part, ExportDefinition definition) +55
   System.ComponentModel.Composition.Hosting.CatalogExportProvider.GetExportedValue(CatalogPart part, ExportDefinition export, Boolean isSharedPart) +78
   System.ComponentModel.Composition.Hosting.CatalogExport.GetExportedValueCore() +47
   System.ComponentModel.Composition.Primitives.Export.get_Value() +57
   System.ComponentModel.Composition.ExportServices.GetCastedExportedValue(Export export) +40
   System.ComponentModel.Composition.<>c__DisplayClassa`1.<CreateStronglyTypedLazyOfT>b__6() +39
   System.Lazy`1.CreateValue() +416
   System.Lazy`1.LazyInitValue() +382
   System.Lazy`1.get_Value() +75
   MefContrib.Web.Mvc.<>c__DisplayClass4.<GetControllerType>b__0(Lazy`1 e) +53
   System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +204
   System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +381
   System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
   MefContrib.Web.Mvc.CompositionControllerFactory.GetControllerType(RequestContext requestContext, String controllerName) +412
   System.Web.Mvc.DefaultControllerFactory.System.Web.Mvc.IControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, String controllerName) +61
   System.Web.Mvc.MvcRouteHandler.GetSessionStateBehavior(RequestContext requestContext) +122
   System.Web.Mvc.MvcRouteHandler.GetHttpHandler(RequestContext requestContext) +33
   System.Web.Mvc.MvcRouteHandler.System.Web.Routing.IRouteHandler.GetHttpHandler(RequestContext requestContext) +10
   System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) +9709884
   System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) +82
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +136
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +699

我的问题是“为什么?” 为什么它试图实例化这个控制器?我在哪里可以确定是什么原因造成的。我很确定在“找不到页面”上实例化每个控制器不是预期的行为。

我不知道该去哪里找。有人可以指出我的方向吗?

更新:

原来是下面的 SetControllerFactory 方法导致了这个问题:

// Tell MVC3 to use MEF as its dependency resolver.
var dependencyResolver = new CompositionDependencyResolver(catalog);
DependencyResolver.SetResolver(dependencyResolver);

// Tell MVC3 to resolve dependencies in controllers
ControllerBuilder.Current.SetControllerFactory(
    new CompositionControllerFactory(
        new CompositionControllerActivator(dependencyResolver)));

注释掉“告诉 MVC3 解决控制器中的依赖关系”部分解决了我的问题,除了我要求的控制器之外,没有控制器被实例化。幸运的是,只有在您不使用标准 Asp.Net 控制器分辨率时才需要这样做(我们也是)。

4

2 回答 2

2

这归结为MefContrib.Web.Mvc中的一个错误。这个程序集实现了它自己的 ControllerFactory ,它继承自DefaultControllerFactory

工厂覆盖GetControllerType,我假设尝试解决存在于默认应用程序或其引用以外的程序集中的控制器。GetControllerType 的实现首先调用base.GetControllerType看Defaultcontroller 是否可以解决。

如果它不能 - 这是不存在的 url 的情况 - 它会向 MEF 询问所有实现 IController 的导出。这将返回一个IEnumerable<Lazy<IController>>,其中每个在 bin/ 文件夹中实现 IController 的类都有一项(默认情况下)。

然后它在 IEnumerable 上运行 linq 查询,对每个 Lazy<IController> 的 Value 属性调用GetType()。请求 Lazy<T> 的值会强制创建实例。这就是为什么 bin/ 中的每个控制器都是为不存在的页面构建的。

我认为这不是一个容易正确解决的问题,因为在不创建值的情况下无法从 Lazy<T>.Value 获取 Type 实例。但是,通过从 AppStart_MefContribMVC3.cs 中删除向 Asp.Net 注册 ControllerFactory 的行 - 您实际上已经停止使用 MefContrib.Web.Mvc 的 ControllerFactory 并且只使用 Asp.Net 的 DefaultControllerFactory 。

于 2013-08-13T09:57:54.747 回答
0

原来是下面的 SetControllerFactory 方法导致了这个问题:

// Tell MVC3 to use MEF as its dependency resolver.
var dependencyResolver = new CompositionDependencyResolver(catalog);
DependencyResolver.SetResolver(dependencyResolver);

// Tell MVC3 to resolve dependencies in controllers
ControllerBuilder.Current.SetControllerFactory(
    new CompositionControllerFactory(
        new CompositionControllerActivator(dependencyResolver)));

注释掉“告诉 MVC3 解决控制器中的依赖关系”部分解决了我的问题,除了我要求的控制器之外,没有控制器被实例化。幸运的是,只有在您不使用标准 Asp.Net 控制器分辨率时才需要这样做(我们也是)。

于 2013-08-12T13:32:32.763 回答