Problem with missing global session.

Apr 15, 2011 at 12:58 PM

I'm trying to convert the Agent Desktop reference implementation into a more MVVM friendly architecture so that I can move the code behind out of the views into a much more testable architecture. On the whole, this has gone relatively well, but I am having a problem with no global session being created. The application starts up, and reaches the point where it's attempting to start the global session and starting global applications. It hit's the AddSession method internally, and errors with "GlobalSessionNotStarted: A global session has not started!  You cannot start a normal session (those tied to a customer) until a global session has started."

The stack trace at this point is:

   at Microsoft.Uii.Csr.ApplicationHost.InitializeWorkItem(String id)
   at Microsoft.Uii.Csr.ApplicationHost..ctor(Guid sessionID, Boolean globalSession, Boolean useContextProxy)
   at Microsoft.Uii.Csr.Session.Init(String name, Int32 callId, Boolean useContextProxy)
   at Microsoft.Uii.Csr.Session..ctor(String name, Int32 callId, Guid sessionId, Boolean useContextProxy)
   at Microsoft.Uii.Csr.Session..ctor(String name, Int32 callId)
   at Microsoft.Uii.Desktop.SessionManager.AgentDesktopSession..ctor(String name, CustomerEntity customer)
   at xxx.AddSession(String name, Int32 callId, Object customer) in xxx\MvvmSessions.cs:line 21

For the life of me, I can't figure out how to add the global session. So that this works properly. Any help that you can give would be appreciated.

Apr 15, 2011 at 5:29 PM

Hard to tell w/out seeing what your doing :)

However,

Usally that error comes from not intilaizing the shell ( program.cs ) before loading the window.  
The desktop must be a AifWpfShellBase or a AifWinformShellBase.

Are you still using the UII Services class from the Refernace ?

thanks

Mattb-MSFT

Apr 18, 2011 at 12:02 PM
Edited Apr 18, 2011 at 1:16 PM

OK. I've modified the application to use the following code:  

desktop.StartApplication();

This throws the following error :

Service Microsoft.Uii.Csr.ApplicationHostWorkItem is not available in the current context.

   at Microsoft.Practices.CompositeUI.Collections.ServiceCollection.Get(Type serviceType, Boolean ensureExists)
   at Microsoft.Practices.CompositeUI.ServiceDependencyAttribute.ServiceDependencyParameter.GetValue(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder.PropertySetterInfo.GetValue(IBuilderContext context, Type type, String id, PropertyInfo propInfo)
   at Microsoft.Practices.ObjectBuilder.PropertySetterStrategy.InjectProperties(IBuilderContext context, Object obj, String id)
   at Microsoft.Practices.ObjectBuilder.PropertySetterStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.CreationStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.ReflectionStrategy`1.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.ReflectionStrategy`1.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.ReflectionStrategy`1.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.SingletonStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.TypeMappingStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id)
   at Microsoft.Practices.ObjectBuilder.BuilderBase`1.DoBuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies)
   at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies)
   at Microsoft.Practices.CompositeUI.Collections.ManagedObjectCollection`1.BuildFirstTimeItem(Type typeToBuild, String idToBuild, Object item)
   at Microsoft.Practices.CompositeUI.Collections.ManagedObjectCollection`1.Build(Type typeToBuild, String idToBuild, Object item)
   at Microsoft.Practices.CompositeUI.Collections.ManagedObjectCollection`1.Add(TItem item, String id)
   at Microsoft.Practices.CompositeUI.Collections.ManagedObjectCollection`1.Add(TItem item)
   at Microsoft.Practices.CompositeUI.Windows.BuilderStrategies.FrameworkElementSmartPartStrategy.AddToWorkItem(WorkItem workItem, Object item)
   at Microsoft.Practices.CompositeUI.Windows.BuilderStrategies.FrameworkElementSmartPartStrategy.AddHierarchy(WorkItem workItem, FrameworkElement frameworkElement)
   at Microsoft.Practices.CompositeUI.Windows.BuilderStrategies.FrameworkElementSmartPartStrategy.AddHierarchy(WorkItem workItem, FrameworkElement frameworkElement)
   at Microsoft.Practices.CompositeUI.Windows.BuilderStrategies.FrameworkElementSmartPartStrategy.AddHierarchy(WorkItem workItem, FrameworkElement frameworkElement)
   at Microsoft.Practices.CompositeUI.Windows.BuilderStrategies.FrameworkElementSmartPartStrategy.AddHierarchy(WorkItem workItem, FrameworkElement frameworkElement)
   at Microsoft.Practices.CompositeUI.Windows.BuilderStrategies.FrameworkElementSmartPartStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.CompositeUI.Windows.Activation.FrameworkElementActivationStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.CompositeUI.Windows.BuilderStrategies.WindowsServiceStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.CompositeUI.BuilderStrategies.RootWorkItemInitializationStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.CompositeUI.BuilderStrategies.CommandStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.CompositeUI.BuilderStrategies.EventBrokerStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.MethodExecutionStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.PropertySetterStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.CreationStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.ReflectionStrategy`1.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.ReflectionStrategy`1.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.ReflectionStrategy`1.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.SingletonStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.TypeMappingStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id)
   at Microsoft.Practices.ObjectBuilder.BuilderBase`1.DoBuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies)
   at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies)
   at Microsoft.Practices.CompositeUI.Collections.ManagedObjectCollection`1.BuildFirstTimeItem(Type typeToBuild, String idToBuild, Object item)
   at Microsoft.Practices.CompositeUI.Collections.ManagedObjectCollection`1.Build(Type typeToBuild, String idToBuild, Object item)
   at Microsoft.Practices.CompositeUI.Collections.ManagedObjectCollection`1.AddNew(Type typeToBuild, String id)
   at Microsoft.Practices.CompositeUI.Collections.ManagedObjectCollection`1.AddNew[TTypeToBuild]()
   at Microsoft.Practices.CompositeUI.CabShellApplication`2.OnRootWorkItemInitialized()
   at Microsoft.Practices.CompositeUI.BuilderStrategies.RootWorkItemInitializationStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.CompositeUI.BuilderStrategies.CommandStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.CompositeUI.BuilderStrategies.EventBrokerStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.MethodExecutionStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.PropertySetterStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.CreationStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.ReflectionStrategy`1.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.ReflectionStrategy`1.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.ReflectionStrategy`1.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.SingletonStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.TypeMappingStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id)
   at Microsoft.Practices.ObjectBuilder.BuilderBase`1.DoBuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies)
   at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies)
   at Microsoft.Practices.CompositeUI.WorkItem.BuildUp()
   at Microsoft.Practices.CompositeUI.CabApplication`1.Run()
   at Microsoft.Uii.Csr.AifWpfShellBase`1.StartApplication()
   at XXX.Mvvm.IntegratedDesktop.Program.Main() in C:\Work\Mvvm\XXX.Mvvm.IntegratedDesktop\Program.cs:line 36

I can't find any details online about this error.

Logging shows nothing on this error. MainWindow is a standard Wpf Window.

Apr 18, 2011 at 2:51 PM

Ok, so it sounds like your basing your desktop off AifWpfShellBase, like this :
AifWpfShellBase<Desktop2> desktop = null;

And when you invoke it:
desktop = new AifWpfShellBase<Desktop2>();
desktop.StartApplication();

And your desktop should be based on Window IE:
public partial class Desktop2 : Window

Can you post the constructor you have for your desktop… I think I know what the issue is… I just want to make sure so I don’t send you down a rabbit hole.

If you want you can PM me with that if you don’t want to post it.

MattB – MSFT

Apr 18, 2011 at 4:05 PM
Edited Apr 18, 2011 at 5:01 PM

Thanks for that Matt. The constructor is a plain vanilla WPF constructor that looks like this:

 

 

public MainWindow()

 

{

InitializeComponent(); 

new DesktopMvvmService("Agent Desktop", this);

}

Basically, the DesktopMvvmService implements the DesktopWpf base. Internally it uses a messenger based implementation to notify ViewModels that it's been created.

Apr 18, 2011 at 5:59 PM
Edited Apr 18, 2011 at 8:23 PM

Ok.

So a few mechanics you need to be aware of.

UII ( the core engine ) initializes itself based on the loaded event of the shell that hosts it, AFTER you have called the initialize event.

So when you create DesktopMvvmService, you will need to pass a pointer to the current desktop, which you pass onto base..

For example:

public class UiiServices : WpfDesktop
{

/// <summary>
/// Pointer to the local desktop form.
/// </summary>
Desktop2 localDesktop;


/// <summary>
/// Base constructor for UII.
/// </summary>
/// <param name="productName">Name of the desktop, this is used in logging</param>
/// <param name="desktopFrm">Pointer to the desktop form</param>
public UiiServices(string productName, Desktop2 desktopFrm)
   : base(productName, desktopFrm)
{
   localDesktop = desktopFrm;
}
....
}

On the loaded event of the Desktop, You’re going to want to do any connection work you need to do to connect to CRM and initialize the AuthencationService from AIF Services. *** very important that you do this before you raise or start UII.. Else you will get init Errors.

Once your done with that Generally you want to do something like this :

--->

// Unwire the window loaded event as we will use that to trigger the UII Loading Sequence once the Login to CRM is complete
this.Loaded -= MainAgentDesktop_Loaded;

// Start Uii Init process here.
DesktopServices = new UiiServices(uiResources.APPLICATION_NAME, this);

// Get the Max Uii Sessions permitted.
int iMaxSessionCount = DesktopServices.MaxNumberOfSessionsPermitted;

// Create Session Object.
SessionManager = new AgentDesktopSessions(true, iMaxSessionCount, Convert.ToBoolean(ConfigurationValueReader.ConfigurationReader().ReadAppSettings("LoadSessions")));

// Wire Uii Loader Events.
DesktopServices.LoaderStatusUpdated += new EventHandler<DesktopLoaderStatusUpdateEventArgs>(DesktopServices_CcfLoaderStatusUpdated);
DesktopServices.LoaderComplete += new EventHandler<DesktopInitAndLogOnEventArgs>(DesktopServices_CcfLoaderComplete);
DesktopServices.LoaderAppLoadingStatusUpdated += new EventHandler<DesktopLoaderStatusUpdateEventArgs>(DesktopServices_CcfLoaderAppLoadingStatusUpdated);

// Spin it up...
DesktopServices.InitializeDesktop(SessionManager);

//UII is design to trigger its own initiation when the “Loaded” event of a WPF desktop is fired,
//Because we needed to handle a multistage login and failure in WPF, we need to invoke this event directly.
this.RaiseEvent(new RoutedEventArgs(FrameworkElement.LoadedEvent));

<---

When the Loaded Event gets raised the second time… all of UII initializes and the global session starts.

If that doesn’t fix it for you, Direct message me and I will send you a basic working shell with nothing else in it so you can see the basic mechanics.

MattB-MSFT

Apr 18, 2011 at 8:26 PM

Thanks Matt. That seems to be getting me closer - when I raise the LoadedEvent though, I get the following error: "Object reference not set to an instance of an object.". The StackTrace is:

   at Microsoft.Uii.Csr.ApplicationHost.InitializeWorkItem(String id)
   at Microsoft.Uii.Csr.ApplicationHost..ctor(Guid sessionID, Boolean globalSession, Boolean useContextProxy)
   at Microsoft.Uii.Csr.Session.Init(String name, Int32 callId, Boolean useContextProxy)
   at Microsoft.Uii.Csr.Session..ctor(String name, Int32 callId, Guid sessionId, Boolean useContextProxy)
   at Microsoft.Uii.Desktop.SessionManager.AgentDesktopSession..ctor(String name, Int32 callId, CustomerEntity customer, Boolean useContextProxy)
   at Microsoft.Uii.Desktop.SessionManager.AgentDesktopSessions.CreateSession(String name, Int32 callId, Object customer)
   at Microsoft.Uii.Csr.Sessions.AddSession(String name, Int32 callId, Object customer)
   at Microsoft.Uii.Desktop.UI.Core.DesktopBase.StartNewSession(AgentDesktopSession session, String sessionName, CustomerEntity customer, Guid callID, IContextManager CtxMgr)
   at Microsoft.Uii.Desktop.UI.Core.DesktopBase.AddSession(CustomerEntity customer, Guid callID)
   at Microsoft.Uii.Desktop.UI.Core.DesktopBase.StartHostedApplications()
   at Microsoft.Uii.Desktop.UI.Core.DesktopLoader.DoLoginStep(LoginSteps loginSteps)
   at Microsoft.Uii.Desktop.UI.Core.DesktopLoader.LoadNonHostedApplications(IApplicationService applicationService)
   at Microsoft.Uii.Desktop.UI.Core.DesktopLoader.GetNonHostedApps()
   at Microsoft.Uii.Desktop.UI.Core.DesktopLoader.DoLoginStep(LoginSteps loginSteps)
   at Microsoft.Uii.Desktop.UI.Core.DesktopLoader.Login()
   at Microsoft.Uii.Desktop.UI.Core.DesktopLoader.DoLoginStep(LoginSteps loginSteps)
   at Microsoft.Uii.Desktop.UI.Core.DesktopLoader.GetOptions()
   at Microsoft.Uii.Desktop.UI.Core.DesktopLoader.DoLoginStep(LoginSteps loginSteps)
   at Microsoft.Uii.Desktop.UI.Core.DesktopLoader.LoadDesktop()
   at Microsoft.Uii.Desktop.UI.Core.DesktopBase.StartDesktopLoad()
   at Microsoft.Uii.Desktop.UI.Wpf.WpfDesktop.WpfRootDesktopForm_Loaded(Object sender, RoutedEventArgs e)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
   at BarclaysWealth.Mvvm.Infrastructure.DesktopViewModel.HookupDesktopService(DesktopMvvmService service) in C:\Work\Mvvm\XXX.Mvvm.Infrastructure\ViewModels\DesktopViewModel.cs:line 117

I really appreciate all your help on this.

Apr 21, 2011 at 10:43 AM

MattB helped me to get to the bottom of the issue. There were two basic problems at play here. They were:

  1. We had directly placed a hosted control on the WPF desktop.
  2. The UII loading sequence was occurring before we had completed the authentication sequence in CRM.

Now that we've sorted these items out, our MVVMed version of CCA is working as we'd expect.

Feb 24, 2012 at 8:50 PM

Hello Matt and ohanlonp

I am currently struggling with exact the same details. Also trying to implement a Mvvmed agentdesktop. The reason for this challenge is that I am responsible for the design of an agent desktop that needs to based on wpf and mvvmed so it uses all the benefits of this framework.

So my question is if you could send me some of the sourcecode or at least the design principles that you applied when moving towards mvvmed.

You would really help me out for the project i am working on.

Regards, Wim 

Feb 28, 2012 at 1:45 PM

In the last situation, the problem was that the session was being created too early in the process,

Keep in mind that UII “owns” the desktop, and needs to be initialized in the initial shell setup, program.cs vs. the app.cs for WPF.  Next, you need to deal with Initializing the UII Session manager which by default ( in the CCA example ), it tied to the OnLoad Event of the main window of the application.

This is probably the root of your issue.

What I suggest you do is download the Solution Starters for UII, you can find them here. Then create a new Desktop Solution and look at how the Desktop is created, CRM Auth occurs, and Session Load starts.  That will probably sort it out for you.

(For a Info on how to use the solution starters… see this post here. after you download them.)

If not ping me again directly and I will need to look at your code help much further.

 

As a comment here.. I usually do not bother making the desktop shell MVVM, in UII it’s a lot of extra work for not much gain if you follow the design principle that the shell should never contain business logic.

I do use the MVVM ( or MVC depending on what I’m doing) pattern the WPF hosted controls

Mattb-msft

Feb 29, 2012 at 9:20 AM

Hello Matt,

Thanks for the reply. I got the application running using the Load event hint from the original posting. In our project, the focus is on quality and testing. One other design rational is that WPF is designed to use mvvm. Last reason to use mvvm on global application level is that our functional designers define screen flows on main application level plus on sub-proces level. I am glad that our team managed to solve the UII session initialization issue, plus some others. let me explain a bit:

- we use a main FlowController that manages the Views that are sequentially displayed in the main application View.

- each view is mapped to its own viewmodel

- the UII engine is wrapped/hosted in a global Dataservice that is injected in each Viewmodel throught the [Import] attribute.

-the main window code-behind only creates the WPFDesktop class and injects a reference to itself in the constructor.

-the UII engine (data service then creates a sessionmanager and initializes the UII engine

-When we need to host a application inside a View, we dynamically add a panel to the UII engine by calling the AddPanel method of the WPFDesktop service.

-then we create the Dynamic Hosted Application on this panel.

-When leaving/destroying the View, we close the dynamic application and remove the panel

-The focus of the application design is more and more on web service instead of GUI automation. That's why the mvvm model is favoured to encourage flexibility compared to one main application window with code behind.

Thanks for your support,

Wim

Some code:

    public partial class MainAppWindow : Window
    {
        public MainAppWindow()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainAppWindow_Loaded);
        }

        void MainAppWindow_Loaded(object sender, RoutedEventArgs e)
        {
            AuthenticationService authenticationService = (AuthenticationService)AifServiceContainer.Instance.GetService<AuthenticationService>();

            string authenticationMode = ConfigurationManager.AppSettings["authenticationMode"];
            if (null == authenticationMode)
                authenticationMode = string.Empty;
            string organizationServiceUrlString = ConfigurationManager.AppSettings["organizationServiceUrl"];
            authenticationService.Connect(new Uri(organizationServiceUrlString), new NetworkCredential("user", "pwd", "CORP"));

            this.Loaded -= this.MainAppWindow_Loaded;
            //=================================================================================================
            // Start the UII engine hosted as a MVVM data service
            //=================================================================================================
            MyDesktopService myservice = new MyDesktopService("AgentDesktop", this);

            MainAppViewModel vm = this.DataContext as MainAppViewModel;
            vm.InitializeUIIEngineCommand.Execute(myservice);

            //=================================================================================================
            // Next line is necessary to load UII engine
            //=================================================================================================
            this.RaiseEvent(new RoutedEventArgs(FrameworkElement.LoadedEvent));
            //=================================================================================================
            WindowState = WindowState.Maximized;
        }

 

And the UII Engine data servce 

    [ExportService(ServiceType.Both, typeof(IUIIDataService))]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public class UIIDataService : NotifyPropertyChangedBase, IUIIDataService, IWPFPanel
    {
        private Sessions m_sessionManager = null;
        private Microsoft.Uii.Desktop.UI.Wpf.WpfDesktop m_desktopService = null;

        public Microsoft.Uii.Desktop.UI.Wpf.WpfDesktop DesktopService
        {
            get
            {
                return m_desktopService;
            }
            set
            {
                m_desktopService = value;
            }
        }
        public Sessions SessionManager
        {
            get
            {
                return m_sessionManager;
            }
            set
            {
                m_sessionManager = value;
            }
        }

        public UIIDataService() {}

        public void InitializeDesktop()
        {
            DesktopService.LoaderComplete +=new EventHandler<DesktopInitAndLogOnEventArgs>(DesktopService_LoaderComplete);
            DesktopService.InitializeDesktop(SessionManager);
        }

 At last the Main ViewModel

    [ExportViewModel("MainAppViewModel")]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class MainAppViewModel : BaseViewModel, IMainViewModel
    {
        private IBaseViewModel m_currentView;
        private IMainFlowController m_controller;
        private IUIIDataService m_windowUIIService;

        public SimpleCommand<Object, Object> ReStartCommand { get; private set; }
        public SimpleCommand<Object, Object> ExitCommand { get; private set; }
        public SimpleCommand<Object, Object> InitializeUIIEngineCommand { get; private set; }

        public IBaseViewModel CurrentView
        {
            get { return m_currentView; }
            set
            {
                m_currentView = value;
                OnPropertyChanged(() => CurrentView);
            }
        }

        [Import]
        public IUIIDataService WindowUIIService
        {
            get { return m_windowUIIService; }
            set
            {
                m_windowUIIService = value;
            }
        }

        [ImportingConstructor]
        public MainAppViewModel(IMainFlowController flowController)
        {
            m_controller = flowController;
            m_controller.MainViewModel = this;
            ReStartCommand = new SimpleCommand<object, object>((object o) => m_controller.Restart());
            InitializeUIIEngineCommand = new SimpleCommand<object, object>((object o) => InitializeUIIEngine(o));
        }

        private void InitializeUIIEngine(object o)
        {
            WindowUIIService.DesktopService = o as Microsoft.Uii.Desktop.UI.Wpf.WpfDesktop;
            int iMaxSessionCount = WindowUIIService.DesktopService.MaxNumberOfSessionsPermitted;
            bool loadSessions = Convert.ToBoolean(ConfigurationValueReader.ConfigurationReader().ReadAppSettings("LoadSessions"), CultureInfo.CurrentUICulture);
            WindowUIIService.SessionManager = new AgentDesktopSessions(true, iMaxSessionCount, loadSessions);
            WindowUIIService.InitializeDesktop();
        }
    }

Feb 29, 2012 at 3:10 PM
Edited Feb 29, 2012 at 3:12 PM

So a few things…

First to clarify what sounds like a misconception,
WPF is not designed to use MVVM. I know that blend implies that in via one of the templates. However it’s just that, a template.

MVVM is one of the many frameworks available for app dev on WPF, Silverlight, and Asp.net, all of which are good and have value… but they are not “built in”.

Also based on your code your using the MEFedMVVM class lib from codeplex/nuget, which is an extension to MEF and is not developed by MS. Personally, I have been keeping an eye on it as it is quite interesting what the developer is doing with it.

 

Now on your approach,.

I’m puzzled by why you’re doing this..

If I’m reading your statement correctly, you are trying to wrap the desktopbase in a container, then reinitialize it for every instance of a “view” that you have,

Is that what you’re doing here?

For clarity,
UII is a form of MEF ( built for a different purpose ). You generally would not use them together at the shell level as they conceptually conflict, and will create some rather complex and unnecessary code.

In UII the DesktopBase is the base container.   WPF Hosted Controls are the equivalent to Views.
The “Session” is tied to the initial Instance of the desktop base.. Global hosted controls are loaded to it based on configuration from the CRM server, and then instanced applications or controls are loaded on the fly based on session requirements and your code.

It’s often the case where Hosted Controls are built up in a MVM or MVVM model and in some cases use MEF at that level.

Also, your described approach to using AddPanel sounds like it will not work. Calls to add panel must happen prior to the call to initialize desktop.

If you would like to discuss in depth, feel free to PM me.

mattb-msft