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

时间:2011-08-16 22:21:08

标签: c# wcf dependency-injection mef

我正在尝试将特定的类注入我的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没有为我初始化这个课程。我错过了什么吗?

编辑:

当我检查目录时 - 我看到我的类已导出但我看不到它在任何地方导入... enter image description here

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

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

3 个答案:

答案 0 :(得分:5)

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

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

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

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

答案 1 :(得分:2)

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

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

基本上,您需要实现一个支持MEF的自定义实例提供程序,并且可以在创建时组成WCF服务对象。

答案 2 :(得分:0)

我写了一篇关于如何以基于这里的配置的通用方式编写WCF的方法:

Unit Testing, WCF and MEF

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