Как сказать MEF воссоздать объект?

Я использую mef для создания веб-сервисов WCF. Так выглядит сервис:

[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 и заголовки во время построения и заполняет «контекст». С таким кодом, как у меня, он создается с первого раза и никогда не уничтожается. Как изменить это поведение?

Спасибо!


person katit    schedule 18.08.2011    source источник


Ответы (2)


При экспорте реализации IContextManager необходимо пометить экспорт политикой создания неразделяемых частей. Например:

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

Это сообщит MEF, что он должен создавать новый экземпляр экспорта каждый раз, когда он удовлетворяет требованиям импорта. По умолчанию MEF использует CreationPolicy.Shared, который создаст только одно экспортируемое значение (синглетон), что, вероятно, вам нужно для реализаций электронной почты и ведения журнала.

person Tim Roberts    schedule 18.08.2011
comment
У него проблемы с ContextManager, с двумя другими все в порядке. - person Chris Charabaruk; 18.08.2011
comment
имейте в виду, что если вы импортируете что-то вроде Lazy‹IContextManager›, вы всегда получаете один и тот же экземпляр из-за Lazy‹›, независимо от того, является ли CreationPolicy Nonshared или Shared. Представьте случай с [ImportMany] и метаданными. - person blindmeis; 19.08.2011
comment
Чтобы уточнить комментарий от blinkmeis: политика создания неразделяемых частей действительно приводит к разным экземплярам, ​​если вы вызываете .Value в двух разных экземплярах Lazy<IContextManager>. Вы получите один и тот же экземпляр менеджера контекста только в том случае, если вы неоднократно извлекаете .Value из одного и того же отложенного импорта в одном и том же объекте. - person Wim Coenen; 19.08.2011

Вы можете сделать создание части «необщим», установив его в атрибуте PartCreationPolicyAttribute экспортируемого класса или в свойстве RequiredCreationPolicy ImportAttribute.

Это создаст новый экземпляр класса с экспортом каждый раз, когда будет удовлетворен импорт. Если это не совсем то, что вам нужно, вы можете взглянуть на ExportFactory или контейнеры с ограниченной областью действия. Однако если вы используете версию MEF для .NET 4, ExportFactory не поддерживается, и вам придется проделать гораздо больше работы для определения области действия. Вы можете получить предварительную версию следующей версии MEF на mef.codeplex.com.

person Daniel Plaisted    schedule 18.08.2011
comment
Здравствуйте, Даниил, это совершенно случайно, но у меня есть похожий вопрос, может быть, вы можете его проверить? stackoverflow.com/questions/32901056/ - person Jannik; 03.10.2015