/// <summary> /// Does all the setup of a DownloaderManager, including using Factories to construct Validators and Downloaders that it will use. /// Builds all the stuff up, constructs the DownloaderManager. Packages the Mgr with its Thread in a DnldMgrHolder struct and returns it. /// **NOTE: this follows a variant of the Builder Pattern, where we delegate constuction of a complex object. /// could also have been in a separate Builder or Factory class but small enough to put here. /// </summary> /// <param name="application">the name of the Updater target application</param> /// <returns>DnldMgrHolder struct containing Built DownloaderManager and the Thread it will run on</returns> private DnldMgrHolder SetupDownloadManager(ApplicationConfiguration application) { DownloaderManager dnldMgr = null; // create an instance of a Downloader for DownloaderManager to use: IDownloader downloader = DownloaderFactory.Create(UpdaterConfiguration.Instance); // create instance of Validator for DownloaderManager to use: IValidator validator = ValidatorFactory.Create(UpdaterConfiguration.Instance); // populate application jobentry for shared DownloadJobStatusEntry dnldJob = new DownloadJobStatusEntry(application.Name, Guid.Empty, JobStatus.Ready); // create the ManualResetEvent "mustStop" which we will use later if Stopping to signal "you must stop" to dnld mgr ManualResetEvent mustStop = new ManualResetEvent(false); // create the callback delegate pointed at our RestartUpdater method so we can restart if something fails badly: BadExitCallback badExitCbk = new BadExitCallback(this.RestartUpdater); // create the download manager, feed it our instance of actual downloader dnldMgr = new DownloaderManager(downloader, validator, dnldJob, mustStop, badExitCbk); // create the thread that this dnldMgr + its other objects will run on Thread dnldThread = new Thread(new ThreadStart(dnldMgr.RunDownloader)); dnldThread.Name = "DownloadManagerThread_" + application.Name + "_" + _guidUniqueName.ToString(); // create new holder struct for thread + dnldmgr DnldMgrHolder holder = new DnldMgrHolder(dnldThread, dnldMgr); #region Event Registrations // *** NOTE: we facade all these underlying events through this class to // *** a) avoid exposing dnldMgr class // *** b) so later if we choose to use a better threading model--that is, NOT allow // *** our threads to "venture outside" and possibly dawdle out there (get blocked for instance) // *** then it will be easy to spawn a dedicated eventing thread in here. // *** NOTE: IF we have more than one app we're updating, then we must hook EACH DOWNLOADMANAGER's events. // *** the sinking app will have to distinguish which app fired which event from the event args // REGISTER for DownloaderManager's events--we do not want to expose downloader directly, so // we shuttle its events through this class dnldMgr.ServerManifestDownloaded += new UpdaterActionEventHandler(OnServerManifestDownloaded); dnldMgr.UpdateAvailable += new UpdaterActionEventHandler(OnUpdateAvailable); dnldMgr.DownloadStarted += new UpdaterActionEventHandler(OnDownloadStarted); dnldMgr.DownloadCompleted += new UpdaterActionEventHandler(OnDownloadCompleted); dnldMgr.ManifestValidated += new UpdaterActionEventHandler(OnManifestValidated); dnldMgr.ManifestValidationFailed += new UpdaterActionEventHandler(OnManifestValidationFailed); dnldMgr.FilesValidated += new UpdaterActionEventHandler(OnFilesValidated); dnldMgr.FilesValidationFailed += new UpdaterActionEventHandler(OnFilesValidationFailed); #endregion // return the packaged DnldMgr return(holder); }
/// <summary> /// Only constructor for DownloaderManager. All parameters required for proper function. /// </summary> /// <param name="downloader">instance of IDownloader implementation</param> /// <param name="validator">instance of IValidator implementation</param> /// <param name="downloadJob">encapsulation of Job information in DownloadJobStatusEntry instance, such as app name job status job id</param> /// <param name="mustStop">an MRE used by Updater to tell this object it must clean up and leave or be Interrupt()ed</param> /// <param name="badExitCbk">delegate instance this class will call on on unrecoverable error, such as an unanticpated exception that compromises too badly to contine</param> public DownloaderManager ( IDownloader downloader, IValidator validator, DownloadJobStatusEntry downloadJob, ManualResetEvent mustStop, BadExitCallback badExitCbk ) { _downloader = downloader; _validator = validator; _dnldJob = downloadJob; _mustStopUpdating = mustStop; // using our app's name, look up the application object (ApplicationConfiguration) in array of applications-- // since WE are working on one, but there may be many _application = UpdaterConfiguration.Instance[_dnldJob.ApplicationName]; // set out internal delegate instance of BadExitCallback. // this is the function pointer we'll use to notify UpdaterManager of really poor exits (fatal exceptions etc.) _badExitCbk = badExitCbk; }
/// <summary> /// Only constructor for DownloaderManager. All parameters required for proper function. /// </summary> /// <param name="downloader">instance of IDownloader implementation</param> /// <param name="validator">instance of IValidator implementation</param> /// <param name="downloadJob">encapsulation of Job information in DownloadJobStatusEntry instance, such as app name job status job id</param> /// <param name="mustStop">an MRE used by Updater to tell this object it must clean up and leave or be Interrupt()ed</param> /// <param name="badExitCbk">delegate instance this class will call on on unrecoverable error, such as an unanticpated exception that compromises too badly to contine</param> public DownloaderManager( IDownloader downloader, IValidator validator, DownloadJobStatusEntry downloadJob, ManualResetEvent mustStop, BadExitCallback badExitCbk ) { _downloader = downloader; _validator = validator; _dnldJob = downloadJob; _mustStopUpdating = mustStop; // using our app's name, look up the application object (ApplicationConfiguration) in array of applications-- // since WE are working on one, but there may be many _application = UpdaterConfiguration.Instance[ _dnldJob.ApplicationName ]; // set out internal delegate instance of BadExitCallback. // this is the function pointer we'll use to notify UpdaterManager of really poor exits (fatal exceptions etc.) _badExitCbk = badExitCbk; }
/// <summary> /// Does all the setup of a DownloaderManager, including using Factories to construct Validators and Downloaders that it will use. /// Builds all the stuff up, constructs the DownloaderManager. Packages the Mgr with its Thread in a DnldMgrHolder struct and returns it. /// **NOTE: this follows a variant of the Builder Pattern, where we delegate constuction of a complex object. /// could also have been in a separate Builder or Factory class but small enough to put here. /// </summary> /// <param name="application">the name of the Updater target application</param> /// <returns>DnldMgrHolder struct containing Built DownloaderManager and the Thread it will run on</returns> private DnldMgrHolder SetupDownloadManager( ApplicationConfiguration application ) { DownloaderManager dnldMgr = null; // create an instance of a Downloader for DownloaderManager to use: IDownloader downloader = DownloaderFactory.Create( UpdaterConfiguration.Instance ); // create instance of Validator for DownloaderManager to use: IValidator validator = ValidatorFactory.Create( UpdaterConfiguration.Instance ); // populate application jobentry for shared DownloadJobStatusEntry dnldJob = new DownloadJobStatusEntry( application.Name, Guid.Empty, JobStatus.Ready ); // create the ManualResetEvent "mustStop" which we will use later if Stopping to signal "you must stop" to dnld mgr ManualResetEvent mustStop = new ManualResetEvent( false ); // create the callback delegate pointed at our RestartUpdater method so we can restart if something fails badly: BadExitCallback badExitCbk = new BadExitCallback( this.RestartUpdater ); // create the download manager, feed it our instance of actual downloader dnldMgr = new DownloaderManager( downloader, validator, dnldJob, mustStop, badExitCbk ); // create the thread that this dnldMgr + its other objects will run on Thread dnldThread = new Thread( new ThreadStart( dnldMgr.RunDownloader ) ); dnldThread.Name = "DownloadManagerThread_" + application.Name + "_" + _guidUniqueName.ToString(); // create new holder struct for thread + dnldmgr DnldMgrHolder holder = new DnldMgrHolder( dnldThread, dnldMgr ); #region Event Registrations // *** NOTE: we facade all these underlying events through this class to // *** a) avoid exposing dnldMgr class // *** b) so later if we choose to use a better threading model--that is, NOT allow // *** our threads to "venture outside" and possibly dawdle out there (get blocked for instance) // *** then it will be easy to spawn a dedicated eventing thread in here. // *** NOTE: IF we have more than one app we're updating, then we must hook EACH DOWNLOADMANAGER's events. // *** the sinking app will have to distinguish which app fired which event from the event args // REGISTER for DownloaderManager's events--we do not want to expose downloader directly, so // we shuttle its events through this class dnldMgr.ServerManifestDownloaded += new UpdaterActionEventHandler( OnServerManifestDownloaded ); dnldMgr.UpdateAvailable += new UpdaterActionEventHandler( OnUpdateAvailable ); dnldMgr.DownloadStarted += new UpdaterActionEventHandler( OnDownloadStarted ); dnldMgr.DownloadCompleted += new UpdaterActionEventHandler( OnDownloadCompleted ); dnldMgr.ManifestValidated +=new UpdaterActionEventHandler( OnManifestValidated ); dnldMgr.ManifestValidationFailed +=new UpdaterActionEventHandler( OnManifestValidationFailed ); dnldMgr.FilesValidated +=new UpdaterActionEventHandler( OnFilesValidated ); dnldMgr.FilesValidationFailed +=new UpdaterActionEventHandler( OnFilesValidationFailed ); #endregion // return the packaged DnldMgr return holder; }