0

我在 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% 正确的。

4

3 回答 3

2

我同意@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
}

以及特定于Web的实现:

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 应用程序中使用可执行程序集?

于 2012-07-13T11:26:28.360 回答
1

造成这种情况的一个可能原因是path.

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

如果这是您正在做的事情,请尝试根据以下内容指定路径Assembly.GetExecutingAssembly().Location

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

string binPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
LoadPlugins(binPath);
于 2012-07-13T11:11:50.260 回答
0

在控制台应用程序或 cassini 和 IIS 中运行时的区别在于安全上下文。

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

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

您的 MEF 部件可能位于 NETWORK SERVICE 也无权访问的目录中。

于 2012-07-13T11:12:06.970 回答