IIS下的MEF未加载部件

问题描述:

我在iis下加载mef部件时遇到问题。加载方法如下所示:IIS下的MEF未加载部件

private void LoadPlugins(string path) 
{ 
    var aggregateCatalog = new AggregateCatalog(); 
    var directoryCatalogExe = new DirectoryCatalog(path, "*.exe"); 
    aggregateCatalog.Catalogs.Add(directoryCatalogExe); 
    var container = new CompositionContainer(aggregateCatalog); 
    container.ComposeParts(this); 
} 

该方法在控制台应用程序或卡西尼中完美工作。在iis下,零件数为0 - 没有错误,在事件日志中没有异常,没有任何...

我完全不知道发生了什么事。路径是100%正确的。

+1

你将什么值作为'路径'传递给LoadPlugins? – 2012-07-13 11:06:13

+0

HttpContext.Current.Server.MapPath(configPath)其中configPath看起来像“〜\ Plugin”。最后,路径= D:\ TFS \ Projects \ WebTools \ trunc \ WebTools.UI.Web \ Plugins – eye 2012-07-13 11:55:48

对此的一个可能的原因可能是path的错误值。

例如,您不应该认为当前目录将是您的代码的"bin"目录,因此传递"."可能不是一个好主意。

如果这是你在做什么,可以尝试使用基于Assembly.GetExecutingAssembly().Location的路径:

// using System.IO; 
// using System.Reflection;  

string binPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 
LoadPlugins(binPath); 

的差异,当你在一个控制台应用程序或运行的卡西尼和IIS的安全上下文。

运行控制台应用程序或cassini时,安全上下文是已登录的用户,即您。

在IIS下运行时,安全上下文是应用程序池的标识,默认为NETWORK SERVICE。

这可能是您的MEF部件位于NETWORK SERVICE无法访问的目录中。

我会同意@stakx的评估。我使用不同的方法创建容器,使其更加环境不可知。我创建一个接口:

/// <summary> 
/// Defines the required contract for implementing a composition container factory. 
/// </summary> 
public interface ICompositionContainerFactory 
{ 
    #region Methods 
    /// <summary> 
    /// Creates an instance of <see cref="CompositionContainer"/>. 
    /// </summary> 
    /// <returns>An instance of <see cref="CompositionContainer"/>.</returns> 
    CompositionContainer CreateCompositionContainer(); 
    #endregion 
} 

随着默认实现(在控制台应用程序的工作原理,服务主机):

public class DefaultCompositionContainerFactory : ICompositionContainerFactory 
{ 
    #region Methods 
    /// <summary> 
    /// Creates an instance of <see cref="CompositionContainer"/>. 
    /// </summary> 
    /// <returns> 
    /// An instance of <see cref="CompositionContainer"/>. 
    /// </returns> 
    public CompositionContainer CreateCompositionContainer() 
    { 
     var domain = AppDomain.CurrentDomain; 
     string path = domain.BaseDirectory; 

     // Use the base directory from where the application is running. 
     var catalog = new DirectoryCatalog(path); 

     // Create the container. 
     var container = new CompositionContainer(catalog); 

     return container; 
    } 
    #endregion 
} 

而一个网络具体实施:

public class WebCompositionContainerFactory : ICompositionContainerFactory 
{ 
    #region Methods 
    /// <summary> 
    /// Creates an instance of <see cref="CompositionContainer"/>. 
    /// </summary> 
    /// <returns> 
    /// An instance of <see cref="CompositionContainer"/>. 
    /// </returns> 
    public CompositionContainer CreateCompositionContainer() 
    { 
     string path = HttpRuntime.BinDirectory; 

     // Use the base directory from where the application is running. 
     var catalog = new DirectoryCatalog(path); 

     // Create the container. 
     var container = new CompositionContainer(catalog); 

     return container; 
    } 
    #endregion 
} 

我通过配置连线。

要考虑的另一件事是,您正在传递* .exe作为您的目录过滤器,您是否在您的Web应用程序中使用可执行程序集?