【问题标题】:Trying to inject dependency into IIS hosted WCF service using MEF尝试使用 MEF 将依赖项注入 IIS 托管的 WCF 服务
【发布时间】:2011-08-16 22:21:07
【问题描述】:

我正在尝试将特定类注入我的 WCF 服务,但它不起作用,我不明白为什么。我对 MEF 和模式非常陌生,只是想让它发挥作用。观看了一系列视频以了解它的含义,但在我的情况下引导不起作用,因为它不是 Silverlight http://channel9.msdn.com/blogs/mtaulty/mef--silverlight-4-beta-part-1-introduction

这是我的 Web 应用程序的 Global.asax 代码。这不是 MVC,只是普通的 ASP.NET 应用程序:

private void Application_Start(object sender, EventArgs e)
        {
            RegisterRoutes();

            var catalog = new WebScopedCatalog(new DirectoryCatalog(Server.MapPath("~\\bin"))); 
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }

首先,我不确定我是否正确引导它。第二,我使用http://www.timjroberts.com/2011/02/web-scoped-mef-parts/ 作为网络范围部分的指导。我需要它,因为一些注入的对象应该只在请求期间存在。

现在,我有以下课程:

    [Export(typeof(ITest))]
    [WebPartCreationPolicy(WebCreationPolicy.Session)]
    public class Test : ITest
    {
        public string TestMe()
        {
            return "Hello!";
        }
    }

我的服务看起来像:

[ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class MobileService
    {
        [Import]
        public ITest MyTestClass { get; set; }

        public MobileService()
        {
            int i = 10;
        }

当断点在 i=10 处命中时 - MyTestClass 中有 NULL。显然,MEF 并没有为我初始化这个类。我错过了什么吗?

编辑:

当我检查目录时 - 我看到我的课程已导出,但我没有看到它在任何地方导入...

编辑 2: 丹尼尔,谢谢。这说得通。在这一点上,它对我来说仍然有点像魔法。是的,WCF 创建了这个服务。比我有 MembershipProvider 和各种实用程序类都需要相同的导入。而且我没有创建这两个类,所以我不能让 Mef 创建它们。 (由 WCF 创建的服务,由 who-knows-what 创建的 MembershipProvider,实用程序类具有静态方法..)我想使用 Mef 而不是将我的东西存储在 HttpContext.Current 中。我的容器对象没有 SatisfyImports。它有 SatisfyImportsOnce。如果我在许多不同的构造函数中这样做怎么办? Mef 会共享同一个单例还是每次都会创建新实例?

此时我想知道我是否应该在这种特殊情况下使用 Mef..

【问题讨论】:

    标签: c# wcf dependency-injection mef


    【解决方案1】:

    MEF 不会满足它不创建的对象的导入。是什么创建了 MobileService?如果不是 MEF,则默认不满足导入。即使它是 MEF,在构造函数中也不会满足导入的要求 - 在创建对象之前,您不能在创建的对象上设置属性(即构造函数已完成)。

    您可以调用 container.SatisfyImportsOnce(mobileService) 来满足零件的导入。您应该尽量避免在需要 MEF 导入的任何地方执行此操作。如果可以,您应该导出一个零件并从另一个零件导入它,以便 MEF 为您处理创建。但是,看起来这部分可能是由 WCF 创建的,因此您不能让 MEF 创建它,在这种情况下,使用 SatisfyImportsOnce 就可以了。

    对 EDIT2 的响应:如果您每次都使用相同的容器,MEF 默认情况下只会创建一个带有导出的零件实例。您可以将 CreationPolicy 设置为 NonShared(在导出或导入属性中)以更改此设置。

    至于以您尝试的方式使用 MEF 是否有意义,我对编写 Web 服务的了解还不够,无法就此给您任何建议。

    【讨论】:

    • 我在原始帖子中添加了 EDIT2。你能对此发表评论吗?谢谢!
    • 你说“如果你每次都使用同一个容器”。我相信这是一个主要问题,因为我不确定如何在 asp.net 中保留容器引用
    • @katit 您可能会像您正在做的那样在应用程序启动时创建容器并将其存储在应用程序数据中。
    【解决方案2】:

    我编写的 Web 范围的部件创建策略对 WCF 服务没有帮助。

    我发布了一篇新的博客文章,其中记录了可组合 WCF 服务的方法: http://www.timjroberts.com/2011/08/wcf-services-with-mef/

    基本上,您需要实现一个自定义实例提供程序,该实例提供程序可识别 MEF,并且可以在创建 WCF 服务对象时组合它。

    【讨论】:

      【解决方案3】:

      我写了关于如何以通用方式编写你的 WCF,它的配置基于这里:

      Unit Testing, WCF and MEF

      我实际上是根据 Tim Robert 在他的帖子中提供的代码示例构建了我的解决方案。只是我更进一步,而不是在全局 asax 中使用代码,我将配置移到 web.config 中,以便更容易维护。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-26
        • 2022-12-13
        • 2011-09-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多