2010-08-04 2 views
1

Я пытаюсь понять, почему один из моих объектов, похоже, не удовлетворяет его Импорт. Я думаю, что это может быть способ использования функции container.ComposeParts(), но я не смог найти много документации по этому поводу.MEF Import - ошибка ссылки объекта

У меня есть четыре проекта
MEF.Service.Contracts
MEF.Service.Messaging (реализует контракты)
MEF.Service.Core
MEF.Service.Console

MEF.Service.Contracts содержит простой интерфейс, называемый IMessageService с одной функцией

public interface IMessageService 
{ 
    void SendMessage(string message); 
} 

MEF.Service.Messaging имеет одну реализацию выше

[Export(typeof(IMessageService))] 
public class ConsoleMessageService : IMessageService 
{ 
    #region IMessageService Members 

    public void SendMessage(string message) 
    { 
     Console.WriteLine(message); 
    } 

    #endregion 
} 

MEF.Service.Core имеет класс ServiceManager, который импортирует доступные сервисы. В этом примере IMessageService

public class ServiceManager 
{ 
    [Import] 
    public IMessageService MessageService { get; set; } 
} 

Наконец, в проекте приложения MEF.Service.Console я создаю MEF контейнера с помощью DirectoryCatalog. Затем я создаю экземпляр ServiceManager и вызываю его свойство MessageService.
Однако в этот момент он терпит неудачу с ошибкой ссылки объекта.

Вот код в проекте MEF.Service.Console

class Program 
{ 
    static void Main(string[] args) 
    { 
     Program p = new Program(); 
     p.Run(); 
    } 

    public void Run() 
    { 
     Compose(); 

     ServiceManager manager = new ServiceManager(); 
     manager.MessageService.SendMessage("Test Message"); 

     Console.ReadLine(); 
    } 

    private void Compose() 
    { 
     var catalog = new DirectoryCatalog(@".\"); 
     var container = new CompositionContainer(catalog); 
     container.ComposeParts(this); 
    } 
} 

MEF.Service.Console имеет ссылки на другие три проекта, просто чтобы убедиться, что библиотеки являются в той же папке, во время выполнения.

Я ознакомился с каталогом и контейнером после того, как они были инициализированы, и он содержит мой экспорт ConsoleMessageService в качестве части.

Я пытаюсь выяснить, почему мой [Импорт] MessageService в моем ServiceManager не удовлетворен.

Любая помощь или указатели на составляющие детали и то, как импортеры будут насыщены, будут оценены.

ответ

1

Я довольно новыми для MEF себя, но то, что я вижу здесь это: вы не имеете IMessageService как экземпляр основного приложения - вместо этого, он находится на отдельном объекте ServiecManager, что вы создаете динамически после того, какcontainer.ComposeParts был назван ...

Моя догадка: MEF не получает шанс удовлетворить импорт на ServiceManager так, что объект не вокруг во время композиции.

Предложение: добавить IMessageService экземпляр основного приложения и пусть MEF обрабатывать импорта, а затем передать этот экземпляр в вашу ServiceManager - что-то вроде этого:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Program p = new Program(); 
     p.Run(); 
    } 

    [Import] 
    IMessageService MessageService { get; set; } 

    public void Run() 
    { 
     Compose(); 

     ServiceManager manager = new ServiceManager(MessageService); 
     manager.MessageService.SendMessage("Test Message"); 

     Console.ReadLine(); 
    } 

    private void Compose() 
    { 
     var catalog = new DirectoryCatalog(@".\"); 
     var container = new CompositionContainer(catalog); 
     container.ComposeParts(this); 
    } 
} 

Я уверен, что если вы делаете это таким образом, тогда MEF сможет удовлетворить импорт, и вы получите экземпляр MessageService, который затем можете передать в ServiceManager.

+0

Спасибо. В конце концов я сделал что-то подобное, в результате чего я поместил атрибут Export в свой ServiceManager, а затем импортировал его в свой класс программы. Я думаю, я просто пытаюсь понять, как контейнеры составляют их части и когда. Если проект service.core загружает свой собственный контейнер и использует его или должен быть только одним контейнером в приложении. Трудно найти соответствующую документацию по Рамочной программе в целом, которая пытается объяснить это. – Apocwhen

+0

Не на 100% уверены, что вам сказать - я тоже довольно новичок в этом деле :-) Но я понимаю: с контейнером. Компоновка (это) вы говорите MEF, чтобы разрешить все ссылки в «этом» - класс «Программа». Это не распространяется на ServiceManager, который вы создаете позже (после того, как MEF составил части). Возможно, вам также нужно вызвать ComposeParts в ServiceManager, явно - снова, а не на 100% уверенно .... –

+0

Да, я думаю, это тоже работает. Я также столкнулся с этим предыдущим сообщением, в котором описывалась та же проблема, что и у меня: http://stackoverflow.com/questions/1845892/import-property-always-null-mef-import-issue Мне кажется, мне нужно узнать больше о композиции. Еще раз спасибо. – Apocwhen

Смежные вопросы