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%正确的。
答
对此的一个可能的原因可能是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应用程序中使用可执行程序集?
你将什么值作为'路径'传递给LoadPlugins? – 2012-07-13 11:06:13
HttpContext.Current.Server.MapPath(configPath)其中configPath看起来像“〜\ Plugin”。最后,路径= D:\ TFS \ Projects \ WebTools \ trunc \ WebTools.UI.Web \ Plugins – eye 2012-07-13 11:55:48