Asp.net web api 使用WebApi和MEF时出错:请确保控制器具有无参数公共构造函数

Asp.net web api 使用WebApi和MEF时出错:请确保控制器具有无参数公共构造函数,asp.net-web-api,mef,asp.net-web-api2,Asp.net Web Api,Mef,Asp.net Web Api2,我在VS 2012中使用了MEF和WebAPI 我犯了一个错误 “exceptionMessage”:“尝试创建“ClienteController”类型的控制器时出错。请确保控制器 有一个无参数的公共 构造函数“,”异常类型“:“System.InvalidOperationException” 我在Global.asax.cs中有: public class WebApiApplication : System.Web.HttpApplication { protected void

我在VS 2012中使用了MEF和WebAPI

我犯了一个错误

“exceptionMessage”:“尝试创建“ClienteController”类型的控制器时出错。请确保控制器 有一个无参数的公共 构造函数“,”异常类型“:“System.InvalidOperationException”

我在Global.asax.cs中有:

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        AggregateCatalog catalog = new AggregateCatalog();
        catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
        CompositionContainer container = MEFLoader.Init(catalog.Catalogs);
        DependencyResolver.SetResolver(new MefDependencyResolver(container)); // view controllers
        GlobalConfiguration.Configuration.DependencyResolver = new MefAPIDependencyResolver(container); // web api controllers

    }
在我的MEFLoader课上

    public static CompositionContainer Init(ICollection<ComposablePartCatalog> catalogParts)
    {
        var catalog = new AggregateCatalog();

        catalog.Catalogs.Add(new AssemblyCatalog(typeof(BuscadorClient).Assembly));
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(Core.DataRepositoryFactory).Assembly));
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(Comun.DataContract.BusinessFault).Assembly));

        if (catalogParts != null)
            foreach (var part in catalogParts)
                catalog.Catalogs.Add(part);

        var container = new CompositionContainer(catalog);
        return container;
    }
publicstaticcompositioncontainer Init(ICollection目录部件)
{
var catalog=new AggregateCatalog();
catalog.Catalogs.Add(新的AssemblyCatalog(typeof(BuscadorClient.Assembly));
catalog.Catalogs.Add(新的AssemblyCatalog(typeof(Core.DataRepositoryFactory.Assembly));
catalog.Catalogs.Add(新的AssemblyCatalog(typeof(Comun.DataContract.BusinessFault.Assembly));
如果(catalogParts!=null)
foreach(目录部件中的var部件)
目录.目录.添加(部分);
var容器=新的合成容器(目录);
返回容器;
}
程序集位于集成环境中Webapi应用程序网站的bin文件夹中

注:

在开发环境中,dev local有时会失败,解决方案是“重新编译”WebApi应用程序项目(csproj)

无论如何,在集成环境中失败了

Microsoft.Internal.Collections.WeakReferenceCollection
1.b\u 0(WeakReference w)\r\n位于System.Collections.Generic.List
1.RemoveAll(谓词
1匹配)\r\n位于Microsoft.Internal.Collections.WeakReferenceCollection
1.添加(T项)\r\n位于System.ComponentModel.Composition.Hosting.Importingine.StartSafyingImports(PartManager PartManager,AtomicComposition AtomicComposition)\r\n位于System.ComponentModel.Composition.Hosting.Importingine.TryStatisfyImports(PartManager PartManager,ComponentPart部分,Boolean shouldTrackImports)\r\n位于System.ComponentModel.Composition.Hosting.Importingine.SatisfyImports(ComponentPart部分)\r\n位于System.ComponentModel.Composition.Hosting.CompositionServices.GetExportedValuefromComponentPart(导入引擎、组件部分、导出定义)\r\n位于System.ComponentModel.Composition.Hosting.CatalogExportProvider.GetExportedValue(CatalogPart部分、导出定义导出、布尔值为共享部分)\r\n位于System.ComponentModel.Composition.Primitives.Export.get_Value()\r\n位于System.ComponentModel.Composition.ReflectionModel.ImportingItem.CastSingleExportToImportType(类型类型,导出导出)\r\n位于System.ComponentModel.Composition.ReflectionModel.ReflectionComponentPart.SetImport(导入项目,导出[]导出)\r\n位于System.ComponentModel.Composition.ReflectionModel.ReflectionComponentAsseblePart.SetImport(导入定义,IEnumerable
1导出)\r\n位于System.ComponentModel.Composition.Hosting.Importingine.PartManager.TrySetImport(导入定义导入,导出[]导出)\r\n位于System.ComponentModel.Composition.Hosting.Importingine.TryStatesMachine(PartManager PartManager,IEnumerable
1 imports,AtomicComposition AtomicComposition)\r\n位于System.ComponentModel.Composition.Hosting.Importingine.TryStatesMachine(PartManager PartManager PartManager,ComponentPart部分)\r\n位于System.ComponentModel.Composition.Hosting.Importingine.TryStatisfyImports(PartManager PartManager、ComponentPart part、Boolean shouldTrackImports)\r\n位于System.ComponentModel.Composition.Hosting.Importingine.SatisfyImports(ComponentPart part part)\r\n位于System.ComponentModel.Composition.Hosting.CompositionServices.GetExportedValuefromComponentPart(导入引擎、组件部分、导出定义)\r\n位于System.ComponentModel.Composition.Hosting.CatalogExportProvider.GetExportedValue(CatalogPart部分、导出定义导出、布尔值为共享部分)\r\n位于中的System.ComponentModel.Composition.Primitives.Export.get\u Value()\r\n位于公司..Core.MefExtensions.GetExportedValueByType(CompositionContainer,Type类型)


不确定是否还有人对答案感兴趣,但我在使用MEF作为IoC的WebApi服务中遇到了相同的问题。合成容器是在启动时创建的,带有自定义导出提供程序的列表

问题的原因是导出提供程序不是使用创建的

在这种情况下,除了在创建CompositionContainer时设置线程安全选项外,还应该使用将线程安全设置为true的构造函数创建所有自定义导出提供程序

var aggregate = new AggregateCatalog(assemblyCatalogs);
//create default export provider to be thread safe
var defaultExportProvider = new CatalogExportProvider(aggregate, true);
_compContainer = new CompositionContainer(CompositionOptions.DisableSilentRejection|CompositionOptions.IsThreadSafe, defaultExportProvider);
defaultExportProvider.SourceProvider = _compContainer;

多线程可能有问题我建议将YifanLu的答案标记为正确。当与ASP.NET控制器一起使用时,MEF会莫名其妙地呕吐,唯一的线索是WeakReferenceCollection清理。容器必须实例化为线程安全的。我当然对答案感兴趣(因此是向上投票)。使用WPF(Prism)还有MEF和多线程,并且有一些奇怪的行为。这个在bootstrapper中实现的金块让一切都消失了。谢谢。