MEF 导入问题

发布于 2024-10-07 16:57:48 字数 2782 浏览 0 评论 0原文

我在将 shell-view-model 导入到 view-model 类时遇到问题,我使用 MEF。

Shell-view-model :

namespace Spirit.ViewModels
{
    using Caliburn.Micro;
    using System.ComponentModel.Composition;

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

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

        public void ShowLogOnView()
        {
            ActivateItem(new LogOnViewModel());
        }

        public void ShowMessengerView()
        {
            ActivateItem(new LogOnViewModel());
        }
    }

}

我需要在视图模型类中导入此类:

[Export]
public class LogOnViewModel : Screen, IDataErrorInfo
{

    [Import]
    private IShellViewModel _shellViewModel;


    public void LogOn(string nick, string password)
    {
        IMessengerViewModel vm = IoC.Get<MessengerViewModel>();
        _shellViewModel.ShowMessengerView();
    }
}

问题是初始化后变量 _shellViewModel null。

我的引导程序如下所示:

  public class MefBootStrapper : Bootstrapper<IShellViewModel>
  {

  }

我的解决方案:

我创建接口程序集并在外部服务 dll 和 wpf 应用程序中引用此程序集。

在引导程序中,我使用反射加载此程序集:

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

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

_container = new CompositionContainer(catalog);

然后创建导体类:

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

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

    public void ShowLogOnView()
    {
        ActivateItem(IoC.Get<LogOnViewModel>());
    }

    public void ShowMessengerView()
    {
        ActivateItem(IoC.Get<MessengerViewModel>());
    }
}

在视图模型中我有这个:

  [Export]
    public class LogOnViewModel : Screen, IDataErrorInfo, ILogOnViewModel
    {

        [Import]
        private IShellViewModel _shellViewModel;

        [Import]
        private IPokecConnection _pokecConn;

//this method is bind on event click of button
        public void LogOn(string nick, string password)
        {
            //SHOW NEW WIEW
           _shellViewModel.ShowMessengerView();
        }
    }

I have problem with import shell-view-model to view-model class, I use MEF.

Shell-view-model :

namespace Spirit.ViewModels
{
    using Caliburn.Micro;
    using System.ComponentModel.Composition;

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

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

        public void ShowLogOnView()
        {
            ActivateItem(new LogOnViewModel());
        }

        public void ShowMessengerView()
        {
            ActivateItem(new LogOnViewModel());
        }
    }

}

I need this class import in view-model class:

[Export]
public class LogOnViewModel : Screen, IDataErrorInfo
{

    [Import]
    private IShellViewModel _shellViewModel;


    public void LogOn(string nick, string password)
    {
        IMessengerViewModel vm = IoC.Get<MessengerViewModel>();
        _shellViewModel.ShowMessengerView();
    }
}

Problem is after initialize is variable _shellViewModel null.

My bootstraper look like this:

  public class MefBootStrapper : Bootstrapper<IShellViewModel>
  {

  }

MY SOLUTION:

I create interface assembly and refer this assembly in external service dll and also in wpf app.

In bootstraper I load this assembly with reflection:

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

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

_container = new CompositionContainer(catalog);

Than I create conductor class:

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

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

    public void ShowLogOnView()
    {
        ActivateItem(IoC.Get<LogOnViewModel>());
    }

    public void ShowMessengerView()
    {
        ActivateItem(IoC.Get<MessengerViewModel>());
    }
}

And in view-model I have this:

  [Export]
    public class LogOnViewModel : Screen, IDataErrorInfo, ILogOnViewModel
    {

        [Import]
        private IShellViewModel _shellViewModel;

        [Import]
        private IPokecConnection _pokecConn;

//this method is bind on event click of button
        public void LogOn(string nick, string password)
        {
            //SHOW NEW WIEW
           _shellViewModel.ShowMessengerView();
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文