Для приложения MVC, использующего MEF, иногда я получаю erorr ""
У меня есть решение .NET с
- Один проект веб-приложения MVC и,
- Многие проекты библиотек классов, которые занимаются аутентификацией, получением конфигураций, выполнением внешних вызовов API и т. Д.
Я настроил MEF, как показано ниже, с помощью кода и развернул его на веб-сервере с использованием IIS. Наблюдал ошибку ниже пару раз, после чего я пытался загрузить страницу несколько раз, но она по-прежнему выдает ту же ошибку.
После обновления пула приложений исчезает только ошибка. Я изо всех сил пытался отладить и понять ошибку, но безуспешно. Я неправильно настраиваю MEF где-нибудь?

Global.asax:
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
var pluginFolders = LoadMefComponents();
Bootstrapper.Compose(pluginFolders);
IControllerFactory mefControllerFactory = new MefControllerFactory(Bootstrapper.Container);
ControllerBuilder.Current.SetControllerFactory(mefControllerFactory);
}
protected List<string> LoadMefComponents()
{
var pluginFolders = new List<string>();
string ModulesPath = CommonUtility.GetApplicationDirectory();
var plugins = Directory.GetDirectories(ModulesPath).ToList();
plugins.ForEach(path =>
{
var directoryInfo = new DirectoryInfo(path);
pluginFolders.Add(directoryInfo.Name);
});
return pluginFolders;
}
}
MEFControllerFactory.cs: этот файл находится в App_Start
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();
}
}
Bootstrapper.cs: этот файл находится в App_Start
public class Bootstrapper
{
private static CompositionContainer compositionContainer;
private static bool IsLoaded = false;
public static CompositionContainer Container
{
get { return compositionContainer; }
set { compositionContainer = value; }
}
public static void Compose(List<string> pluginFolders)
{
if (IsLoaded) return;
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
catalog.Catalogs.Add(new DirectoryCatalog(CommonUtility.GetApplicationDirectory()));
compositionContainer = new CompositionContainer(catalog);
compositionContainer.ComposeParts();
IsLoaded = true;
}
public static T GetInstance<T>(string contractName = null)
{
var type = default(T);
if (compositionContainer == null) return type;
if (!string.IsNullOrWhiteSpace(contractName))
type = compositionContainer.GetExportedValue<T>(contractName);
else
type = compositionContainer.GetExportedValue<T>();
return type;
}
}
CommonUtility.cs: этот файл находится в App_Start
public class CommonUtility
{
public static string GetApplicationDirectory()
{
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
}
}
HomeController.cs:
[CommonExceptionFilter]
public class HomeController : Controller
{
private IConfigurationManager _configurationManager;
[ImportingConstructor]
public HomeController()
{
_configurationManager = Bootstrapper.GetInstance<IConfigurationManager>();
}
public async Task<ActionResult> Index()
{
//Business Logic
return View()
}
}
IConfigurationManager.cs
[InheritedExport]
public interface IConfigurationManager
{
string GetConfigurationValue(string keyName)
}
ConfigurationManager.cs
[PartCreationPolicy(CreationPolicy.Shared)]
public class ConfigurationManager: IConfigurationManager
{
[ImportingConstructor]
public ConfigurationManager()
{
}
public string GetConfigurationValue(string keyName)
{
return "";
}
}
IHttpHandlers, используемые в проекте MVC:
public class CommonServiceHandler : HttpTaskAsyncHandler, IRequiresSessionState
{
private ICommonServiceHandlerManager _commonServiceHandlerManager;
public CommonServiceHandler()
{
_commonServiceHandlerManager = Bootstrapper.GetInstance<ICommonServiceHandlerManager>();
}
public override bool IsReusable
{
get
{
return false;
}
}
}