我剛剛將MVC4應用程序更新爲MVC5,出於某種原因,這似乎已經完全破壞了我的MEF實現。將MVC4和WebAPI更新爲MVC5和WebAPI 2破解MEF實現
從我的解決方案下面的代碼片段已經運行了一年多,並且我不完全清楚解決方案是什麼。
我有兩個解決方案,一個MVC5網站和一個MVC WebAPI 2解決方案。
我看到一個網站上的錯誤是:
"Currently composing another batch in this ComposablePartExportProvider. Only one batch can be composed at a time."
而且對解決方案的WebAPI沒有[導入]的標記在控制器類字段將被填充,併產生「對象未設置爲一個對象的實例「。考慮到相同的代碼已經運行了一年多,沒有任何問題,所有這些都非常混亂。
從檢查容器部件中可以看到所有預期的和必需的部件。
MVC5網站MEF配置
public static class MefConfig
{
public static void RegisterMef()
{
var container = ConfigureContainer();
ControllerBuilder.Current.SetControllerFactory(new MefControllerFactory(container));
GlobalConfiguration.Configuration.DependencyResolver = new MefControllerFactory(container);
}
private static CompositionContainer ConfigureContainer()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()));
catalog.Catalogs.Add(new DirectoryCatalog(Path.Combine(MoodConfig.AppBaseDirectory, @"bin\plugins")));
var container = new CompositionContainer(catalog, true);
return container;
}
的WebAPI 2 MEF配置
public static class MefConfig
{
public static void RegisterMef()
{
var container = ConfigureContainer();
ControllerBuilder.Current.SetControllerFactory(new MefControllerFactory(container));
GlobalConfiguration.Configuration.DependencyResolver = new MefControllerFactory(container);
}
private static CompositionContainer ConfigureContainer()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()));
catalog.Catalogs.Add(new DirectoryCatalog(Path.Combine(ConfigHelper.AppBaseDirectory, @"bin\plugins")));
var container = new CompositionContainer(catalog, true);
return container;
}
}
MefControllerFactory
public class MefControllerFactory : DefaultControllerFactory, System.Web.Http.Dependencies.IDependencyResolver
{
private readonly CompositionContainer _compositionContainer;
private bool _disposed;
public MefControllerFactory(CompositionContainer compositionContainer)
{
_compositionContainer = compositionContainer;
}
public IDependencyScope BeginScope()
{
return this;
}
public object GetService(Type serviceType)
{
var export = _compositionContainer.GetExports(serviceType, null, string.Empty).SingleOrDefault();
return null != export ? export.Value : null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
var exports = _compositionContainer.GetExports(serviceType, null, string.Empty);
return exports.Select(export => export.Value).ToList();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
var baseMessage = "Not Found, controllerType is null";
if (requestContext != null)
{
throw new HttpException(404, string.Format("{0} RequestedUrl: {1}", baseMessage, requestContext.HttpContext.Request.Url));
}
throw new HttpException(404, baseMessage);
}
var export = _compositionContainer.GetExports(controllerType, null, string.Empty).SingleOrDefault();
IController result;
if (null != export)
{
result = export.Value as IController;
}
else
{
result = base.GetControllerInstance(requestContext, controllerType);
_compositionContainer.ComposeParts(result);
}
return result;
}
private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Dispose managed resources.
}
}
_disposed = true;
}
}
個所有在這兩種解決方案的控制器都標這樣的:
[Export(typeof(MyController)), PartCreationPolicy(CreationPolicy.NonShared)]
什麼我發現真的很令人困惑的是,這個相同的代碼已經運行不用其他的問題很長一段時間,因爲我還沒有改變.NET版本(4.5)這應該運行相同的MEF代碼。
顯然有一個問題,我在做什麼,我讀過使用ComposeParts方法改變使用SatisfyImportsOnce方法修復問題。當我更改代碼以使用此方法時,儘管部件位於容器中,但我不再在API控制器上獲得batch composing
錯誤,但我的[Import]
屬性仍爲空。
我真的不清楚爲什麼在升級更新版本的MVC和WebAPI後,爲什麼這開始發生,我不清楚最終解決方案是什麼。
我的實現在很大程度上是基於這樣的:
http://kennytordeur.blogspot.co.uk/2012/08/mef-in-aspnet-mvc-4-and-webapi.html
有沒有人見過類似的固定呢?你的情況有什麼修復?
自從問這個問題以來,我已經嘗試了各種解決方案,並且它徹底壞了。看起來WebAPI2在這方面的工作有很大的不同,任何人得到這個信息都會有幫助。 – Jammer