Skip to content

WpfBaFactory Class

Richard Martin edited this page Mar 25, 2024 · 2 revisions

Bootstrapper.WpfBaFactory

When the bundle starts, a factory is used to build out the BA. The BootstrapperApplicationFactory assembly attribute informs the bundle which class is the factory.

[assembly: BootstrapperApplicationFactory(typeof(WpfBaFactory))]

You must supply a factory that inherits from BaseBootstrapperApplicationFactory and override the Create method to build up and return your bootstrapper app. Since this is a factory, it's an appropriate place to build up the models your app needs.

Create Method

There are a lot of events exposed by our bootstrapper application, BootstrapperApp. This is a good place to subscribe to them.

Warning

You should not construct any user interface elements when building out your bootstrapper app. Do not create any windows. Do not associate a Dispatcher with the thread that the factory's Create method is running in. You'll have to build out your UI once your bootstrapper app is running.

Exceptions

You'll notice the code in the Create method is wrapped in a try...catch. This will be a recurring theme that you'll see a lot. Threads will frequently be used to perform tasks. You should assume nothing about the thread any given method is running in. All shared state should be accessible using thread safe techniques. Every event handler should handle its own exceptions, and so should any method that is executed by the WiX framework. In addition to this, I also suggest setting up a handler for unhandled exceptions. That doesn't need to happen until your BA is running, so I use the Dispatcher.UnhandledException event to deal with these.

If you're handling exceptions in your code, where will these unhandled exceptions come from? You can trigger these by supplying the WiX framework with data it's not designed to handle. WiX processes running in the background can trigger these. Logging these exceptions will be useful for debugging.

UI Facade

Looking in the Create method, you'll see a uiFacade. You'll also notice it's injected into a model.

var uiFacade = new WpfFacade(new Log(engine), commandInfo.Display);
var model = new Model(engine, commandInfo, uiFacade);

That model is "The Model" in our MVVM pattern. But what's a UI facade? The facade pattern allows us to expose only the needed functionality of our selected UI framework. This helps to organize our code. We'll cover this in more depth when reviewing the WpfFacade class.

The Model

As for the model, it's a convenience class that puts all the WiX models, shared app state, and UI access in one place. It also exposes some convenience methods. It's easier to inject this into view models and the rest of the BA code instead of separate WiX models.

Subscribing Events

After constructing the BA, some methods are called to subscribe to events.

SubscribeCancelEvents(ba, model);
SubscribeProgressEvents(ba, model);

SubscribeDetectEvents(ba, model);
SubscribePlanEvents(ba, model);
SubscribeApplyEvents(ba, model);

These are split into the detect, plan, and apply phases, but there are also a couple that deal with cancellation and progress.

If you look closely at these methods, you'll notice they all instantiate a class that handles specific events, but references to those instances aren't maintained. Each of these has the model injected into them. These event handlers deal with the majority of detecting and managing the packages in the bundle during the install.

Previous: WiX Config || Next: BootstrapperApp Class

Clone this wiki locally