Can I develop XBAP application with this framework?

Jul 8, 2008 at 9:19 AM
Have anyone tried to develop  XBAP application using this Prism framework ? If yes, what did you do in CreateShell() method of BootStarpper so show the startup page? can anyone give any code example ? Thanks in advance.
Jul 29, 2008 at 2:55 PM
To create a PRSIM XBAP I had to tackle the following issues:

1. XBAPs are partial trust applications by default.
Add the AllowPartiallyTrustedCallers attribute to assemblyinfo of the three CAL projects.
2. The Shell of an XBAP is not a Window but a Page.
Since Page does not have a .Show(), we cannot create its visualtree in the CreateShell() override of our Bootstrapper.
The way I solved this was by adding StartupUri="Shell.xaml" to the Application tag of App.xaml.
To our bootstrapper I added:

public static DependencyObject ShellPage { private get; set; }

protected override DependencyObject CreateShell()
       return ShellPage;

The Shell page gets the following constructor:

public Shell()
    Bootstrapper.ShellPage = this;

That's it.

Jul 30, 2008 at 12:53 AM
Flash demo / code of the CompositeWPF's  Commanding solution running under both CompositeWPF and XBAP available HERE; I like sjappie's approach - I took the approach of bootstrapping from the Page1 codebehind (versus the shell).
Jul 30, 2008 at 12:58 PM
Thanks Bill for the nice flash movie.
Have you ever tried deploying the XBAP in IIS? I can't get it to work there.
It turns out that Composite.Moduleloader requires FileIO permission. This is not granted in partial trust.
Security permissions must be less strict in debug mode, because it works there.
Jul 31, 2008 at 1:35 AM

Thanks sjappie for alerting me to the fact that a CompositeWPF XBAP application requires full trust to execute under IIS!  I had a false sense of security (no pun intended) thinking that since it ran in Debug that it would deploy.

In the following blog How to run WPF - XBAP as Full Trust Application the author does a great job providing step-by-step instructions for preparing an XBAP application for deployment as a full trust application.   I applied the steps and ran into the same things he did (Vista Ultimate/IIS7) - more about it HERE

Jul 31, 2008 at 3:58 AM
Many many thanks sjappie for your answer
Jul 31, 2008 at 9:00 AM
Edited Jul 31, 2008 at 1:23 PM
Hi Bill, thanks for your help. Eventually, I may end up building a full trust XBAP anyway.
But the full trust is required by the module loader only. So I created a custom module loader that doesn't do any File IO. Fortunately Composite WPF is very extensible through the use of services, so this was not a big problem.
I made the following custom implementation of IModuleLoader, that overrides ModuleLoader's LoadAssembly method. 

    public class PartialTrustModuleLoader : ModuleLoader
        private readonly ILoggerFacade loggerFacade;

        public PartialTrustModuleLoader(IContainerFacade containerFacade, ILoggerFacade loggerFacade)
            : base(containerFacade, loggerFacade)
            this.loggerFacade = loggerFacade;

        protected override Assembly LoadAssembly(ModuleInfo moduleInfo)
            string moduleAssembly = moduleInfo.AssemblyFile;

            if (String.IsNullOrEmpty(moduleAssembly))
                throw new ArgumentException("assemblyFile");

            Assembly assembly;
            if (LoadedAssemblies.ContainsKey(moduleAssembly))
                return LoadedAssemblies[moduleAssembly];

                assembly = Assembly.Load(moduleAssembly);
                LoadedAssemblies.Add(moduleAssembly, assembly);
                loggerFacade.Log(string.Format("Loaded module: {0}", moduleInfo.ModuleName), Category.Info, Priority.None);
            catch (Exception ex)
                throw new ModuleLoadException(null, moduleAssembly, ex.Message, ex);
            return assembly;

I also had to make a custom implementation of IModuleEnumerator, because Composite WPF's StaticModuleEnumerator reads moduleType.Assembly.Location ,which requires Sytem.File.IO. 

public PartialTrustModuleEnumerator AddModule(Type moduleType, params string[] dependsOn)
   ModuleInfo moduleInfo = new ModuleInfo(moduleType.Assembly.FullName
                                              , moduleType.FullName
                                              , moduleType.Name
                                              , dependsOn);
   return this;

There is no difference with the StaticModuleEnumerator apart from the moduleType.Assembly.FullName argument to ModuleInfo.

The last thing left to do is override ConfigureContainer() in our Bootstrapper and register our own module loader there.
protected override void ConfigureContainer()
   Container.RegisterType(typeof(IModuleLoader), typeof(PartialTrustModuleLoader), new ContainerControlledLifetimeManager());

That's it. My Composite WPF XBAP is running partial trust in IIS on my machine now. Let me know if you still experience difficulties.

P.S. I use Bill's method of running the bootstrapper from Page1's constructor, rather than the solution I suggested before, because it may happen that Page1 is not yet loaded when the bootstrapper is run.

Jul 31, 2008 at 1:18 PM
Very nice!!! Thanks for sharing the code with us - I'll plug it in tonight when I get home to see how it works :)