Wpf 进口的MEF问题

Wpf 进口的MEF问题,wpf,dependency-injection,inversion-of-control,mef,Wpf,Dependency Injection,Inversion Of Control,Mef,来自具有抽象工厂模式的shell视图模型的模型。我需要从外部组件中注入视图模型类。如果在创建视图模型时使用抽象工厂模式。问题是视图模型中导入的类为空 Shell视图模型如下所示: public interface IViewModelFactory { ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel); IMessengerViewModel CreateMesseng

来自具有抽象工厂模式的shell视图模型的模型。我需要从外部组件中注入视图模型类。如果在创建视图模型时使用抽象工厂模式。问题是视图模型中导入的类为空

Shell视图模型如下所示:

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);
        }
    }
变量_pokeconn为空,因为我使用抽象工厂创建新的视图模型

如果在shell视图模型中使用此选项:

var model = IoC.Get<LogOnViewModel>();
并在视图模型类上添加Export属性它工作得很好,但我想使用抽象工厂,并只在视图模型中注入External程序集中的类。 它存在这个问题的解决方案,或者我必须从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
    }
公共类MefBootStrapper:Bootstrapper
{
#区域字段
私有合成容器_容器;
#端区
#区域覆盖
受保护的覆盖无效配置()
{//配置容器
#如果银光
_container=CompositionHost.Initialize(
新建AggregateCatalog(AssemblySource.Instance.Select(x=>newAssemblyCatalog(x)).OfType());
#否则
变量目录=
新AggregateCatalog(
Select(x=>newAssemblyCatalog(x)).OfType();
//添加外部DLL
catalog.Catalogs.Add(
新建AssemblyCatalog(string.Format(
CultureInfo.InvariantCulture,“{0}{1}”,System.IO.Directory.GetCurrentDirectory(),@“\Pokec_Toolkit.dll”);
_容器=新的合成容器(目录);
#恩迪夫
var batch=新的CompositionBatch();
AddExportedValue(新的WindowManager());
AddExportedValue(新的EventAggregator());
batch.AddExportedValue(_容器);
_容器。组成(批);
_集装箱。满足进口(本);
}
受保护的覆盖对象GetInstance(类型serviceType,字符串键)
{
string contract=string.IsNullOrEmpty(key)?AttributedModelServices.GetContractName(serviceType):key;
var exports=\u container.GetExportedValues(合同);
如果(exports.Count()>0)
返回导出;
抛出新异常(string.Format(“找不到合同{0}.”,合同的任何实例”);
}
受保护的重写IEnumerable GetAllInstances(类型serviceType)
{
返回_container.GetExportedValues(AttributedModelServices.GetContractName(serviceType));
}
受保护的覆盖空洞堆积(对象实例)
{
_container.SatisfyImportsOnce(实例);
}
#端区
}

您是否忘记了LogOnViewModel构造函数的属性导入构造函数


编辑:

否,我使用MEF创建了工厂编号为的新视图模型。我只需要将一个类导入到视图模型类中。私有IPokeConnection\u pokeconn=此处导入类。Vie模型类是在shell-view-Model中创建的。很抱歉,我一直使用构造函数注入。如果你把它变成一个公共属性,比如[Import]public ipokeConnection{get;set;},这会有帮助:Oki,没关系,但是如果我把它变成公共属性,它仍然是空的:(MEF没有注入这个接口对象。我想这个解决方案()这并不能解决我的问题。因为他提前导出了类,他想在其中导入一些类。我自己创建了视图模型的安装(不使用MEF;)我只需要MEF就可以将一个或两个类导入视图模型类。
var model = _factory.CreateLogOnViewModel(this);
 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
    }