MEF проблема с импортом - PullRequest
0 голосов
/ 17 декабря 2010

моделей из shell-view-model с абстрактным фабричным рисунком.Мне нужно внедрить в классы View-моделей из внешней сборки.Если я использую абстрактный шаблон фабрики на создание view-моделей.Проблема в том, что импортированные классы в view-моделях имеют нулевое значение.

Shell-view-модели выглядят так:

public interface IViewModelFactory
    {
        ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel);
        IMessengerViewModel CreateMessengerViewModel(IShellViewModel shellViewModel);
    }

    [Export(typeof(IViewModelFactory))]
    public class DefaulFactoryViewModel:IViewModelFactory
    {
        #region Implementation of IViewModelFactory

        public ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel)
        {
            return  new LogOnViewModel(shellViewModel);
        }

        public IMessengerViewModel CreateMessengerViewModel(IShellViewModel shellViewModel)
        {
            return new MessengerViewModel(shellViewModel);
        }

        #endregion
    }


    public interface IShellViewModel
    {
        void ShowLogOnView();
        void ShowMessengerView();
    }

    [Export(typeof(IShellViewModel))]
    public class ShellViewModel : Conductor<IScreen>, IShellViewModel
    {

        private readonly IViewModelFactory _factory;

        [ImportingConstructor]
        public ShellViewModel(IViewModelFactory factory)
        {
            _factory = factory;
            ShowLogOnView();
        }

        public void ShowLogOnView()
        {
            var model = _factory.CreateLogOnViewModel(this);
            // var model = IoC.Get<LogOnViewModel>();
            ActivateItem(model);
        }

        public void ShowMessengerView()
        {
            var model = _factory.CreateMessengerViewModel(this);
            ActivateItem(model);
        }
    }

Некоторые view-model.:

public class LogOnViewModel : Screen,ILogOnViewModel
{
    [Import]//inject class from external assembly
    private IPokecConnection _pokecConn;

    private readonly IShellViewModel _shellViewModel=null;

    private User _user=null;

    public LogOnViewModel(IShellViewModel shellViewModel)
    {
        _shellViewModel = shellViewModel;
        _user = new User();
    }
}

переменная _pokecConn равна нулю, потому что я использую абстрактную фабрику при создании новых моделей представления.

, если я использую в модели представления оболочки это:

var model = IoC.Get<LogOnViewModel>();

вместо этого:

var model = _factory.CreateLogOnViewModel(this);

и добавление атрибута экспорта в классы моделей представления, это хорошо работает, но я бы хотел использовать абстрактную фабрику и вставлять в модель представления только классы из внешней сборки.Это существующее решение по этой проблеме, или я должен создать view-модели из IoC и экспортировать весь класс?Спасибо за продвижение.

РЕДАКТИРОВАНИЕ:

MEF КЛАСС БУСТРАПЕРА:

 public class MefBootStrapper : Bootstrapper<IShellViewModel>
    {
    #region Fields
    private CompositionContainer _container;
    #endregion

    #region Overrides
    protected override void Configure()
    { //  configure container
    #if SILVERLIGHT
        _container = CompositionHost.Initialize(
        new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()));
    #else

        var catalog =
            new AggregateCatalog(
                AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>());

        //add external DLL
        catalog.Catalogs.Add(
            new AssemblyCatalog(string.Format(
                CultureInfo.InvariantCulture, "{0}{1}", System.IO.Directory.GetCurrentDirectory(), @"\Pokec_Toolkit.dll")));

        _container = new CompositionContainer(catalog);
    #endif

        var batch = new CompositionBatch();

        batch.AddExportedValue<IWindowManager>(new WindowManager());
        batch.AddExportedValue<IEventAggregator>(new EventAggregator());
        batch.AddExportedValue(_container);

        _container.Compose(batch);
        _container.SatisfyImportsOnce(this);  
    }

    protected override object GetInstance(Type serviceType, string key)
    {
        string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
        var exports = _container.GetExportedValues<object>(contract);

        if (exports.Count() > 0)
        return exports.First();

        throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
    }

    protected override IEnumerable<object> GetAllInstances(Type serviceType)
    {
        return _container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
    }

    protected override void BuildUp(object instance)
    {
        _container.SatisfyImportsOnce(instance);
    }
    #endregion
    }

1 Ответ

0 голосов
/ 17 декабря 2010

Вы забыли атрибут ImportingConstructor для конструктора LogOnViewModel?

РЕДАКТИРОВАТЬ: Свойство импорта всегда null (проблема импорта MEF)

...