简体   繁体   English

尝试使用 MEF 将依赖项注入 IIS 托管的 WCF 服务

[英]Trying to inject dependency into IIS hosted WCF service using MEF

I'm trying to inject specific class into my WCF service but it doesn't work and I can't understand why.我正在尝试将特定的 class 注入我的 WCF 服务,但它不起作用,我不明白为什么。 I'm VERY NEW to MEF and patterns, just trying to make it work.我对 MEF 和模式非常陌生,只是想让它发挥作用。 Watched series of videos to understand what it is about but bootstraping won't work in my case since it is not Silverlight http://channel9.msdn.com/blogs/mtaulty/mef--silverlight-4-beta-part-1-introduction观看了一系列视频以了解它的含义,但在我的情况下引导不起作用,因为它不是 Silverlight http://channel9.msdn.com/blogs/mtaulty/mef--silverlight-4-beta-part-1 -介绍

Here is my Web application's Global.asax code.这是我的 Web 应用程序的 Global.asax 代码。 This is non MVC, just regular ASP.NET app:这是非 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);
        }

FIRST, I'm not sure I even bootrstrap it properly.. SECOND, I'm using http://www.timjroberts.com/2011/02/web-scoped-mef-parts/ as a guidance for web-scoped parts.首先,我不确定我是否正确地引导它.. 第二,我使用http://www.timjroberts.com/2011/02/web-scoped-mef-parts/作为 web-scoped-mef-parts/ 的指导. I need that because some injected objects supposed to live during request only.我需要它,因为一些注入的对象应该只在请求期间存在。

Now, I have following class:现在,我关注 class:

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

And my service looks like:我的服务看起来像:

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

        public MobileService()
        {
            int i = 10;
        }

When breakpoint hits at i=10 - I have NULL inside MyTestClass.当断点在 i=10 处命中时 - 我在 MyTestClass 中有 NULL。 Clearly, MEF does not initialize this class for me.显然,MEF 并没有为我初始化这个 class。 Am I missing something?我错过了什么吗?

EDIT:编辑:

When I examine catalog - I see my class Exported but I don't see it imported anywhere...当我检查目录时 - 我看到我的 class 已导出,但我没有看到它在任何地方导入......在此处输入图像描述

EDIT 2: Daniel, Thank you.编辑2:丹尼尔,谢谢。 It makes sense.这说得通。 It still feels litle like a magic for me at this point.在这一点上,它对我来说仍然有点像魔法。 Yes, WCF creates this service.是的,WCF 创建了这个服务。 Than I have MembershipProvider and various Utility classes that ALL need the same import.比我有 MembershipProvider 和各种实用程序类都需要相同的导入。 And I'm not creating neither of those classes so I can't have Mef creating them.而且我没有创建这两个类,所以我不能让 Mef 创建它们。 (Service created by WCF, MembershipProvider created by who-knows-what, Utility classes have static methods..) I wanted to use Mef instead of storing my stuff in HttpContext.Current. (由 WCF 创建的服务,由谁知道什么创建的 MembershipProvider,实用程序类有 static 方法..)我想使用 Mef 而不是将我的东西存储在 HttpContext.Current 中。 My container object doesn't have SatisfyImports.我的容器 object 没有 SatisfyImports。 It has SatisfyImportsOnce.它有 SatisfyImportsOnce。 What if I do it in many different constructors?如果我在许多不同的构造函数中这样做怎么办? Will Mef share same singleton or it will be creating new instance every time? Mef 会共享相同的 singleton 还是每次都会创建新实例?

At this point I wonder if I should even use Mef in this particular scenario..在这一点上,我想知道我是否应该在这种特殊情况下使用 Mef..

MEF won't satisfy imports for objects it doesn't create. MEF 不会满足它不创建的对象的导入。 What is it that creates MobileService?是什么创建了 MobileService? If it's not MEF, then the import won't be satisfied by default.如果不是 MEF,则默认不满足导入。 Even if it is MEF, the import wouldn't be satisfied in the constructor- you can't set properties on an object you create until it is done being created (ie the constructor has finished).即使它是 MEF,导入也不会在构造函数中得到满足——您不能在创建的 object 上设置属性,直到创建完成(即构造函数已完成)。

You can call container.SatisfyImportsOnce(mobileService) to satisfy the imports of a part.您可以调用 container.SatisfyImportsOnce(mobileService) 来满足零件的导入。 You should try to avoid doing this everywhere you need a MEF import.您应该尽量避免在需要 MEF 导入的任何地方执行此操作。 If you can, you should export a part and import it from another part so that MEF handles the creation for you.如果可以,您应该导出一个零件并从另一个零件导入它,以便 MEF 为您处理创建。 However, it looks like this part may be created by WCF so you can't have MEF create it, and in that case it would be OK to use SatisfyImportsOnce.但是,看起来这部分可能是由 WCF 创建的,因此您不能让 MEF 创建它,在这种情况下,可以使用 SatisfyImportsOnce。

Response to EDIT2: If you use the same container each time, MEF will by default only create one instance of the part with the export.对 EDIT2 的响应:如果您每次都使用相同的容器,MEF 将默认只创建一个带有导出的零件实例。 You can set the CreationPolicy to NonShared (in either the export or import attribute) to change this.您可以将 CreationPolicy 设置为 NonShared(在导出或导入属性中)以更改此设置。

As for whether it makes sense to use MEF the way you are trying to, I don't know enough about writing web services to give you any advice on that.至于以您尝试的方式使用 MEF 是否有意义,我不太了解编写 web 服务来给您任何建议。

The web-scoped part creation policy that I wrote won't help with WCF services.我编写的 Web 范围的部件创建策略对 WCF 服务没有帮助。

I've posted a new blog post that documents an approach to composeable WCF services: http://www.timjroberts.com/2011/08/wcf-services-with-mef/我发布了一篇新的博客文章,其中记录了可组合 WCF 服务的方法: http://www.timjroberts.com/2011/08/wcf-services-with-mef/

Basically, you need to implement a custom Instance Provider that is MEF-aware and can compose the WCF service object when it is created.基本上,您需要实现一个支持 MEF 的自定义 Instance Provider,并且在创建时可以组成 WCF 服务 object。

I wrote about how to compose your WCF in a generic way that its configuration based here:我写了有关如何以通用方式编写 WCF 的文章,其配置基于此处:

Unit Testing, WCF and MEF 单元测试,WCF 和 MEF

I actually built my solution on the code samples Tim Robert's provided in his post.实际上,我在 Tim Robert 在他的帖子中提供的代码示例上构建了我的解决方案。 only that I took it a bit further and instead of using code in the global asax i moved the configuration into the web.config so its easier to maintain.只是我更进一步,而不是在全局 asax 中使用代码,我将配置移动到 web.config 中,因此更易于维护。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM