【问题标题】:How to tell MEF to re-create object?如何告诉 MEF 重新创建对象?
【发布时间】:2011-08-18 05:16:49
【问题描述】:

我正在使用 mef 创建 WCF Web 服务。这是服务的外观:

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

        [Import] 
        public ILoggerService LoggerService { get; set; }

        [Import] 
        public IContextManager ContextManager { get; set; }

检索服务实例的代码如下所示:

// Get Service instace via MEF        
    public object GetInstance(InstanceContext instanceContext, Message message)
    {
        var lazyInstance = Container.GetExports(ServiceType, null, null).FirstOrDefault();
        var instance = lazyInstance.Value;

        return instance;
    } 

MEF 创建 EmailService、LoggerService,如果没问题,它们会在服务存在的同时快乐地生活。

现在,ContextManager 是不同的动物。在 GetInstance - 我真的很喜欢“杀死”它并重新创建。 ContextManager 在构造过程中研究 URL 和标头并填充“上下文”。使用像我这样的代码 - 它是第一次创建并且永远不会被破坏。如何改变这种行为?

谢谢!

【问题讨论】:

    标签: wcf inversion-of-control mef


    【解决方案1】:

    在导出 IContextManager 的实现时,您需要使用非共享部件创建策略标记导出。例如:

    [Export(typeof(IContextManager)]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class ContextManager : IContextManager
    {
       ...
    }
    

    这将通知 MEF,它应该在每次满足导入时创建一个新的导出实例。默认情况下,MEF 使用 CreationPolicy.Shared,它将仅创建一个导出值(单例),这可能是您对电子邮件和日志记录实现所需要的。

    【讨论】:

    • 他的 ContextManager 有问题,其他两个都很好。
    • 请注意,如果您导入 Lazy 之类的内容,由于 Lazy,无论是 CreationPolicy Nonshared 还是 Shared,您总是会得到相同的实例。想象一下 [ImportMany] 和元数据的情况
    • 澄清blindmeis 的评论:如果您在Lazy<IContextManager> 的两个不同实例上调用.Value,非共享部件创建策略确实会导致不同的实例。如果您从同一对象中的相同延迟导入中重复检索.Value,则只会获得相同的上下文管理器实例。
    【解决方案2】:

    您可以通过在导出类的 PartCreationPolicyAttribute 或 ImportAttribute 的 RequiredCreationPolicy 属性上设置部件的创建为“NonShared”。

    这将在每次满足导入时使用导出创建一个新的类实例。如果这不是您想要的,您可能需要查看 ExportFactory 或作用域容器。但是,如果您使用的是 .NET 4 版本的 MEF,则不支持 ExportFactory,您必须做更多的工作来确定范围。您可以在mef.codeplex.com 获得下一个 MEF 版本的预览。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    • 2019-04-07
    • 2014-03-05
    • 1970-01-01
    相关资源
    最近更新 更多