@@ -26,11 +26,17 @@ namespace GitHub.VisualStudio
26
26
[ PartCreationPolicy ( CreationPolicy . Shared ) ]
27
27
public class UIProvider : IUIProvider , IDisposable
28
28
{
29
+ class OwnedComposablePart
30
+ {
31
+ public object Owner { get ; set ; }
32
+ public ComposablePart Part { get ; set ; }
33
+ }
34
+
29
35
static readonly Logger log = LogManager . GetCurrentClassLogger ( ) ;
30
36
CompositeDisposable disposables = new CompositeDisposable ( ) ;
31
37
readonly IServiceProvider serviceProvider ;
32
38
CompositionContainer tempContainer ;
33
- readonly Dictionary < string , ComposablePart > tempParts ;
39
+ readonly Dictionary < string , OwnedComposablePart > tempParts ;
34
40
ExportLifetimeContext < IUIController > currentUIFlow ;
35
41
readonly Version currentVersion ;
36
42
bool initializingLogging = false ;
@@ -72,7 +78,7 @@ public UIProvider([Import(typeof(SVsServiceProvider))] IServiceProvider serviceP
72
78
{
73
79
SourceProvider = ExportProvider
74
80
} ) ) ;
75
- tempParts = new Dictionary < string , ComposablePart > ( ) ;
81
+ tempParts = new Dictionary < string , OwnedComposablePart > ( ) ;
76
82
}
77
83
78
84
[ return : AllowNull ]
@@ -152,12 +158,12 @@ public Ret GetService<T, Ret>() where Ret : class
152
158
return GetService < T > ( ) as Ret ;
153
159
}
154
160
155
- public void AddService < T > ( T instance )
161
+ public void AddService < T > ( object owner , T instance )
156
162
{
157
- AddService ( typeof ( T ) , instance ) ;
163
+ AddService ( typeof ( T ) , owner , instance ) ;
158
164
}
159
165
160
- public void AddService ( Type t , object instance )
166
+ public void AddService ( Type t , object owner , object instance )
161
167
{
162
168
if ( ! Initialized )
163
169
{
@@ -168,13 +174,23 @@ public void AddService(Type t, object instance)
168
174
var batch = new CompositionBatch ( ) ;
169
175
string contract = AttributedModelServices . GetContractName ( t ) ;
170
176
Debug . Assert ( ! string . IsNullOrEmpty ( contract ) , "Every type must have a contract name" ) ;
177
+
178
+ // we want to remove stale instances of a service, if they exist, regardless of who put them there
179
+ RemoveService ( t , null ) ;
180
+
171
181
var part = batch . AddExportedValue ( contract , instance ) ;
172
182
Debug . Assert ( part != null , "Adding an exported value must return a non-null part" ) ;
173
- tempParts . Add ( contract , part ) ;
183
+ tempParts . Add ( contract , new OwnedComposablePart { Owner = owner , Part = part } ) ;
174
184
tempContainer . Compose ( batch ) ;
175
185
}
176
186
177
- public void RemoveService ( Type t )
187
+ /// <summary>
188
+ /// Removes a service from the catalog
189
+ /// </summary>
190
+ /// <param name="t">The type we want to remove</param>
191
+ /// <param name="owner">The owner, which either has to match what was passed to AddService,
192
+ /// or if it's null, the service will be removed without checking for ownership</param>
193
+ public void RemoveService ( Type t , [ AllowNull ] object owner )
178
194
{
179
195
if ( ! Initialized )
180
196
{
@@ -185,13 +201,14 @@ public void RemoveService(Type t)
185
201
string contract = AttributedModelServices . GetContractName ( t ) ;
186
202
Debug . Assert ( ! string . IsNullOrEmpty ( contract ) , "Every type must have a contract name" ) ;
187
203
188
- ComposablePart part ;
189
-
204
+ OwnedComposablePart part ;
190
205
if ( tempParts . TryGetValue ( contract , out part ) )
191
206
{
207
+ if ( owner != null && part . Owner != owner )
208
+ return ;
192
209
tempParts . Remove ( contract ) ;
193
210
var batch = new CompositionBatch ( ) ;
194
- batch . RemovePart ( part ) ;
211
+ batch . RemovePart ( part . Part ) ;
195
212
tempContainer . Compose ( batch ) ;
196
213
}
197
214
}
0 commit comments