CompositeWPF - Integrating the Managed Add-in Framework (MAF) - Part 1 of ? - App.g.cs

If you are unfamiliar with MAF I would suggest that you start by reading Kent Boogaart's Blog on the topic HERE.  Although he recommends reading an MSDN link (that he provides) before continuing his series I would recommend that you read his MAF Gymnastics: Service Provider blog first; he does a great job in taking a very complex topic and breaking it down into bite-size chunks to help us understand how everything is tied together.   I downloaded the solution he provided (the code is compact and not so overwhelming) and reviewed it while I followed along in his blog, by the time I was finished things started to make sense.  I should note the "limitations" he exposes are an eye-opener (the first I've read on the topic).

Once completed with the above mentioned blog, my curiosity had me going to the beginning - how the application is launched.   I didn't see anything unusual with the exception of the LoaderOptimizationAttribute; a wee bit of research had me realizing that I'm going to save his "Event Hub" blog for later; this attribute was going to be a "risk" for my CompositeWPF goals - WPF takes control of Main and it isn't readily apparent how we can add this attribute.

    5 class Program

    6 {

    7     [LoaderOptimization(LoaderOptimization.MultiDomainHost)]

    8     static int Main(string[] args)

    9     {

   10         Console.WriteLine("Initializing host in AppDomain '{0}'",

   11             AppDomain.CurrentDomain.FriendlyName);

   12 

   13         try

   14         {

   15             return new Host().Run();

   16         }

   17         finally

   18         {

   19             Console.WriteLine();

   20             Console.WriteLine("Host will shut down when you press a key.");

   21             Console.ReadKey();

   22         }

   23     }

   24 }

This adventure was somewhat short-lived, I figured I'd be googling for some time because of my past experiences on the topic - before I provide the "easy" solution to the problem it might help to understand what is going on under the hood.

When you compile an application the Visual Studio Compiler will automatically generate an App.g.cs file containing an App class derived from Application.  This file is automatically generated in the applicable Obj folder (Debug, Release, etc) everytime you compile so any modifications you make will be overwritten:

If you attempt to add a static Main method to your App.xaml.cs file you'll run into the following error:

 

Note: the above code is what I am now actually using, after applying the property change and above code, my SDMS application continues to run as it did before. 

The solution - we have to turn off the creation of the App.g.cs file so that ours will be used (I explain how below).  Bear in mind before you do this that the auto creation of the app.g.cs file is biased by the contents of the App.xaml file so you may have to migrate some code from the App.g.cs App class into your own.  e.g., the following XAML file:

    1 <Application x:Class="MainShell.App"

    2    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    3    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    4    >

    5     <Application.Resources>

    6         <ResourceDictionary>

    7             <ResourceDictionary.MergedDictionaries>

    8                 <ResourceDictionary Source="Styles\styles.xaml"></ResourceDictionary>

    9             </ResourceDictionary.MergedDictionaries>

   10         </ResourceDictionary>

   11     </Application.Resources>

   12 </Application>

Gnerates the following App.gs.cs file (which does more than my replacement does)- note that it has the addition of a InitializeComponent method which handles the above resource: 

   38 public partial class App : System.Windows.Application {

   39 

   40     private bool _contentLoaded;

   41 

   42     /// <summary>

   43     /// InitializeComponent

   44     /// </summary>

   45     [System.Diagnostics.DebuggerNonUserCodeAttribute()]

   46     public void InitializeComponent() {

   47         if (_contentLoaded) {

   48             return;

   49         }

   50         _contentLoaded = true;

   51         System.Uri resourceLocater =

   52             new System.Uri("/MainShell;component/app.xaml",

   53                 System.UriKind.Relative);

   54 

   55         #line 1 "..\..\App.xaml"

   56         System.Windows.Application.LoadComponent(this,

   57             resourceLocater);

   58 

   59         #line default

   60         #line hidden

   61     }

   62 

   63     /// <summary>

   64     /// Application Entry Point.

   65     /// </summary>

   66     [System.STAThreadAttribute()]

   67     [System.Diagnostics.DebuggerNonUserCodeAttribute()]

   68     public static void Main() {

   69         MainShell.App app = new MainShell.App();

   70         app.InitializeComponent();

   71         app.Run();

   72     }

   73 }

THE SOLUTION:

Select the App.xaml file and from properties change the "Build Action" from Application Definition to None and the auto generated file will no longer be created!  TIP: save a copy of the App.g.cs file first so that you can ensure your new Main application does everything it is expected to.   Note: the App.g.cs file will no longer exist in the Obj folder.

Other Links

 


Tags: , ,
Categories:


Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know