在mvvmLight视图模型中使用WebContext时出现问题

问题描述

| 和往常一样,我正在尝试使用一项新技术,并立即遇到问题。 我有一个Silverlight业务应用程序+ MvvmLight。 在我的视图模型中,我尝试获取登录用户的角色:
    public Homeviewmodel()
    {
        if (IsInDesignMode)
        {
            // Code runs in Blend --> create design time data.
        }
        else
        {
            // Code runs \"for real\"                
            DetermineStartableProcesses();
        }
    }

    private void DetermineStartableProcesses()
    {
        _startableProcesses = new ObservableCollection<WorkflowProcess>(
            WebContext.Current.User.Roles.SelectMany(r =>
                WorkflowProcess.GetStartableByRole(r))
                .distinct());
    }
在运行时,出现以下异常:
System.Windows.Markup.XamlParseException occurred
  Message=The invocation of the constructor on type \'CompanyHR.viewmodel.viewmodelLocator\' that matches the specified binding constraints threw an exception. [Line: 18 Position: 57]
  LineNumber=18
  LinePosition=57
  StackTrace:
       at System.Windows.Application.LoadComponent(Object component,Uri resourceLocator)
       at CompanyHR.App.InitializeComponent()
       at CompanyHR.App..ctor()
  InnerException: System.ArgumentNullException
       Message=Value cannot be null.
Parameter name: source
       StackTrace:
            at System.Linq.Enumerable.SelectMany[TSource,TResult](IEnumerable`1 source,Func`2 selector)
            at CompanyHR.viewmodel.Homeviewmodel.DetermineStartableProcesses()
            at CompanyHR.viewmodel.Homeviewmodel..ctor()
            at CompanyHR.viewmodel.viewmodelLocator..ctor()
       InnerException: 
看起来viewmodelLocator正在创建Webcontext get之前在应用启动时实例化viewmodel,这意味着在viewmodel构造函数中做很多工作对我来说是个坏主意。 因此,我应该在viewmodel中的哪个位置检索将获得数据绑定的数据?     

解决方法

在App构造函数中实例化WebContext。然后在调用之前将其添加到App_startup中的资源中
public App()
        {
            Startup += Application_Startup;
            Exit += Application_Exit;
            UnhandledException += Application_UnhandledException;

            if (IsInDesignModeStatic)
            {
                Services.ServiceLoader.LoadDesignTimeServices();
                DispatcherHelper.Initialize();
            }
            else
            {
                try
                {

                    ServiceLoader.LoadRunTimeServices();
                    DispatcherHelper.Initialize();

                    WebContext webContext = new WebContext();
                    ApplicationLifetimeObjects.Add(WebContext.Current);

                    FormsAuthentication fa = new FormsAuthentication();
                    fa.DomainContext = new Web.Services.AuthenticationDomainContext();
                    WebContext.Current.Authentication = fa;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }

            InitializeComponent();
        }



private void Application_Startup(object sender,StartupEventArgs e)
        {
            this.Resources.Add(\"WebContext\",WebContext.Current);

            RootVisual = new MainPage();

        }
我发现由于我的自定义AuthenticationDomainContext和Membershipprovider使得在后面的代码中执行此部分更容易...但是Dereks也很好用,我在使所有工作正常的同时使用了后面的代码。     ,这就是我在使用mvvm-light时避免的方式。因此,首先创建WebContext。 在App.xaml中:
 <Application.ApplicationLifetimeObjects>
        <ct:WebContext>
            <ct:WebContext.Authentication>
                <as:FormsAuthentication DomainContextType=\"MyProj.Data.AuthenticationContext,MyProj.Client.Common,Version=1.0.0.\" />
            </ct:WebContext.Authentication>
        </ct:WebContext>
    </Application.ApplicationLifetimeObjects>
    <Application.Resources>
        <ResourceDictionary>

            <ct:ViewModelLocator x:Key=\"Locator\"
                                 d:IsDataSource=\"True\" />
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source=\"Assets/Styles.xaml\" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>