1: public class HostService : IApplicationService, IApplicationLifetimeAware, IPartImportsSatisfiedNotification
2: {
3: /// <summary>
4: /// Gets or sets the context.
5: /// </summary>
6: /// <value>The context.</value>
7: public ApplicationServiceContext Context { get; set; }
8: /// <summary>
9: /// Gets or sets the current.
10: /// </summary>
11: /// <value>The current.</value>
12: public static HostService Current { get; private set; }
13:
14: /// <summary>
15: /// Gets or sets the initialized.
16: /// </summary>
17: /// <value>The initialized.</value>
18: private List<IApplicationService> Initialized { get; set; }
19:
20: /// <summary>
21: /// Gets or sets the services.
22: /// </summary>
23: /// <value>The services.</value>
24: [ImportMany(AllowRecomposition = true, RequiredCreationPolicy = CreationPolicy.Shared)]
25: public List<IApplicationService> Services { get; set; }
26:
27: /// <summary>
28: /// Initializes a new instance of the <see cref="HostService"/> class.
29: /// </summary>
30: public HostService()
31: {
32: if (HostService.Current != null)
33: throw new InvalidOperationException("Service already exists");
34:
35: HostService.Current = this;
36: this.Initialized = new List<IApplicationService>();
37: }
38:
39: /// <summary>
40: /// Called by an application immediately after the <see cref="E:System.Windows.Application.Exit"/> event occurs.
41: /// </summary>
42: public void Exited()
43: {
44: foreach (IApplicationLifetimeAware service in this.Services.OfType<IApplicationLifetimeAware>())
45: service.Exited();
46: }
47:
48: /// <summary>
49: /// Called by an application immediately before the <see cref="E:System.Windows.Application.Exit"/> event occurs.
50: /// </summary>
51: public void Exiting()
52: {
53: foreach (IApplicationLifetimeAware service in this.Services.OfType<IApplicationLifetimeAware>())
54: service.Exiting();
55: }
56:
57: /// <summary>
58: /// Called by an application immediately after the <see cref="E:System.Windows.Application.Startup"/> event occurs.
59: /// </summary>
60: public void Started()
61: {
62: CompositionInitializer.SatisfyImports(this);
63: }
64:
65: /// <summary>
66: /// Called by an application immediately before the <see cref="E:System.Windows.Application.Startup"/> event occurs.
67: /// </summary>
68: public void Starting()
69: {
70: }
71:
72: /// <summary>
73: /// Called by an application in order to initialize the application extension service.
74: /// </summary>
75: /// <param name="context">Provides information about the application state.</param>
76: public void StartService(ApplicationServiceContext context)
77: {
78: this.Context = context;
79: }
80:
81: /// <summary>
82: /// Called by an application in order to stop the application extension service.
83: /// </summary>
84: public void StopService()
85: {
86: foreach (IApplicationService service in this.Services)
87: service.StopService();
88: }
89:
90: /// <summary>
91: /// Called when a part's imports have been satisfied and it is safe to use.
92: /// </summary>
93: public void OnImportsSatisfied()
94: {
95: // buffer for services that raises exception during initialization
96: List<IApplicationService> errors = new List<IApplicationService>();
97:
98: // call StartService
99: foreach (IApplicationService service in this.Services.OfType<IApplicationService>().Except(this.Initialized))
100: {
101: try
102: {
103: service.StartService(this.Context);
104: }
105: catch
106: {
107: errors.Add(service);
108: }
109: }
110:
111: // call Starting
112: foreach (IApplicationLifetimeAware service in
113: this.Services.OfType<IApplicationLifetimeAware>()
114: .Except(this.Initialized.OfType<IApplicationLifetimeAware>())
115: .Except(errors.OfType<IApplicationLifetimeAware>()))
116: {
117: try
118: {
119: service.Starting();
120: }
121: catch
122: {
123: errors.Add((IApplicationService)service);
124: }
125: }
126:
127: // call Started
128: foreach (IApplicationLifetimeAware service in
129: this.Services.OfType<IApplicationLifetimeAware>()
130: .Except(this.Initialized.OfType<IApplicationLifetimeAware>())
131: .Except(errors.OfType<IApplicationLifetimeAware>()))
132: {
133: try
134: {
135: service.Started();
136: }
137: catch
138: {
139: errors.Add((IApplicationService)service);
140: }
141: }
142:
143: // register ad Initialized to avoid duplicated initialization in case of recomposition
144: foreach (IApplicationService service in
145: this.Services.OfType<IApplicationService>()
146: .Except(this.Initialized)
147: .Except(errors))
148: this.Initialized.Add(service);
149:
150: // remove services that raised exceptions
151: foreach (IApplicationService service in errors)
152: this.Services.Remove(service);
153: }
154: }