我已经在MVC应用程序中实现了MEF,并已部署到生产环境。但是有时,使控制器实例进入功能GetControllerInstance
会引发错误。
有没有办法处理GetControllerInstance
函数引发的错误,并且万一发生异常,请在不使用MEF的情况下创建一个Controller。
MefControllerFactory的详细代码:
public class MefControllerFactory : DefaultControllerFactory
{
private readonly CompositionContainer _container;
private readonly Dictionary<IController, Lazy<object, object>> exports;
private readonly object syncRoot;
public MefControllerFactory(CompositionContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this._container = container;
this.exports = new Dictionary<IController, Lazy<object, object>>();
this.syncRoot = new object();
}
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
Lazy<object, object> export = _container.GetExports(controllerType, null, null).FirstOrDefault();
var controller = null == export ? base.GetControllerInstance(requestContext, controllerType)
: (IController)export.Value;
lock (this.syncRoot)
{
this.exports.Add(controller, export);
}
return controller;
}
public override void ReleaseController(IController controller)
{
lock (this.syncRoot)
{
var export = this.exports[controller];
this.exports.Remove(controller);
// this._container.ReleaseExport(export);
}
((IDisposable)controller).Dispose();
}
}
在日志记录中,获取以下堆栈跟踪,
Internal error occurred. Additional information: ''.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: Microsoft.Internal.Assumes+InternalErrorException: Internal error occurred. Additional information: ''.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[InternalErrorException: Internal error occurred. Additional information: ''.]
System.ComponentModel.Composition.Hosting.ImportEngine.InPrerequisiteLoop() +284
System.ComponentModel.Composition.Hosting.ImportEngine.TrySatisfyImportsStateMachine(PartManager partManager, ComposablePart part) +1015
System.ComponentModel.Composition.Hosting.ImportEngine.TrySatisfyImports(PartManager partManager, ComposablePart part, Boolean shouldTrackImports) +144
System.ComponentModel.Composition.Hosting.ImportEngine.SatisfyImports(ComposablePart part) +121
System.ComponentModel.Composition.Hosting.CompositionServices.GetExportedValueFromComposedPart(ImportEngine engine, ComposablePart part, ExportDefinition definition) +36
System.ComponentModel.Composition.Hosting.CatalogExportProvider.GetExportedValue(CatalogPart part, ExportDefinition export, Boolean isSharedPart) +86
System.ComponentModel.Composition.Primitives.Export.get_Value() +56
System.ComponentModel.Composition.ExportServices.GetCastedExportedValue(Export export) +39
System.ComponentModel.Composition.Hosting.ExportProvider.GetExportedValueCore(String contractName, ImportCardinality cardinality) +159
myapp.Bootstrapper.GetInstance(String contractName) +175
myapp.Controllers.HomeController..ctor() +97
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +139
System.Activator.CreateInstance(Type type, Boolean nonPublic) +105
System.Activator.CreateInstance(Type type) +12
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +75
[InvalidOperationException: An error occurred when trying to create a controller of type 'myapp.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +242
myapp.MefControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +126
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +103
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +263
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +77
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +1020
System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +195
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +128
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.7.3282.0
HomeController中的构造器:
[CommonExceptionFilter]
public class HomeController : Controller
{
private IHomeManager _homeManager;
[ImportingConstructor]
public HomeController()
{
_homeManager = Bootstrapper.GetInstance<IHomeManager>();
}
}