【问题标题】:MVC3 ImportMany on Constructor Parameter for Exported Controller导出控制器的构造函数参数上的 MVC3 ImportMany
【发布时间】:2011-02-10 15:44:08
【问题描述】:

我有一个使用 MEF 导出并由控制器工厂加载的控制器。

    [Export(Controller)]
    public class MyController : Controller
    {

        private IRepository MyRepsoitory;

        [ImportMany]
        public IEnumerable<MyImportedItem> TestImportItems {get;set;}

        public MyController([ImportMany]IEnumberable<MyImportedItem> items, [Import]IRepository repository)
        {
            // items here is always null
            // However if I grab the container that the ControllerFactory used and tell it ComposeParts on this the TestImportItems will be filled with 50+ items
            // repository however is instantiated appropriately. 

            GlobalItems.Container.ComposeParts(this);
            //Now TestImportItems if filled but my items parameter alway null... how do I get constructor to fill

        }

    }

因此,MEF 创建 MyController 但只创建存储库并为 ImportMany 发送 null,即使它稍后可以使用相同的 Container 填充属性。

同样奇怪的是,如果我做的事情破坏了在 ControllerFactory 中创建 MyConroller 的项目之一。就好像它检查了它是否具有构造函数的部分,但从不将它们推送到 IEnumerable 参数。

我错过了什么?

显然,如果相同的 Container 适用于 (this) 上的 .ComposingParts,我就有可用的部件(并且我反映了在创建控制器时具有适当导入/导出部件的目录。

我可以重写我的类以使用填充属性,但我真的希望我的导入构造函数获得填充集合。

更新:

如果我为导入添加一个简单的包装类,许多 MEF 将加载 [ImportMany] 参数。

所以下面将为我填充 IEnumerable...

public MyController(TestImportClass test, [Import]IRepository repository)
{
    //test.Items != null
}

public class TestImportClass
{

    public IEnumberable<MyImportedItem> Items {get;set;}

    [ImportingConstructor]
    public TestImportClass([ImportMany]IEnumberable<MyImportedItem> items)
    {
        this.Items = items;
    }
}

我在我的实际代码中使用“约定”系统来标记要导出的控制器。也许由于某种原因导致 MEF 不理解初始构造函数参数上的导入?如果是这样的话,虽然我不确定为什么我的 IRepository 总是被填满?

【问题讨论】:

  • 有趣...如果我将控制器构造函数上的参数从 ImportMany IEnumerable<...> 更改为带有构造函数的简单接口类,该构造函数接受 ImportMany 参数它可以工作。无论出于何种原因,MEF 都不想在我的 Contoller 构造函数上填充 ImportMany 参数,但会在链的下一级进行。

标签: constructor import asp.net-mvc-3 mef


【解决方案1】:

当您调用 ComposeParts 时,您传递的是已经构建好的对象。无法在现有对象上再次调用构造函数。 (在这种情况下,如果你这样做了,你最终会得到无限递归)。所以 ComposeParts 不满足构造函数导入。

如果您的控制器以其他方式从容器中拉出,并且您将 ImportingConstructorAttribute 放在构造函数上,则应该满足构造函数导入。

【讨论】:

  • 我只是在做 ComposeParts(调用后构造函数)来表明我可以填充 IEnumerable 属性。然而,控制器本身是从我调用 ComposeParts(this) 的同一个 Container 加载的。 IRepository 确实在构造函数中被实例化,而不是 IEnumerable 参数。这是我的问题。我还测试了在参数上添加 [ImportingConstructor] 属性和 ImportMany 属性的代码,但仍然没有实例化 IEnumerable。
【解决方案2】:

您使用的约定系统可能不支持构造函数参数中的 ImportMany。据推测,该约定不适用于 TestImportClass,这就是 ImportMany 在该构造函数上工作的原因。

我们计划在 MEF 的下一个版本中提供官方约定模型支持,并且我们应该很快会发布一个新的 codeplex 版本,并提供此支持的预览。

【讨论】:

    猜你喜欢
    • 2011-05-21
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多