以下是我遇到的症状:
我在一个地区有一个全新的空控制器:
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控制器分辨率(我们是)时才需要这样做。
答案 0 :(得分:2)
这是 MefContrib.Web.Mvc 中的错误。这个程序集实现了它自己的ControllerFactory,它继承自 DefaultControllerFactory 。
工厂重写 GetControllerType ,我假设尝试解析除默认应用程序或其引用之外的某些位置的控制器。 GetControllerType的实现首先调用 base.GetControllerType 以查看Defaultcontroller是否可以解析它。
如果不能 - 不存在的网址就是这种情况 - 它会向MEF询问实现IController的所有导出。这将返回 IEnumerable&lt; Lazy&lt; IController&gt;&gt; ,其中每个类在bin /文件夹中实现IController(默认情况下)。
然后在IEnumerable上运行linq查询,在每个Lazy&lt; IController&gt;的Value属性上调用 GetType()。请求懒惰&lt; T&gt;的值。强制创建实例。这就是为什么bin /中的每个控制器都是为不存在的页面构建的原因。
我认为这不是一个容易解决的问题,因为无法在不创建值的情况下从Lazy&lt; T&gt; .Value获取Type实例。但是,通过从AppStart_MefContribMVC3.cs中删除使用Asp.Net注册ControllerFactory的行 - 您已经有效地停止使用MefContrib.Web.Mvc的ControllerFactory,而只是使用了Asp.Net的DefaultControllerFactory。
答案 1 :(得分: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控制器分辨率(我们是)时才需要这样做。