@@ -26,11 +26,17 @@ namespace GitHub.VisualStudio
2626 [ PartCreationPolicy ( CreationPolicy . Shared ) ]
2727 public class UIProvider : IUIProvider , IDisposable
2828 {
29+ class OwnedComposablePart
30+ {
31+ public object Owner { get ; set ; }
32+ public ComposablePart Part { get ; set ; }
33+ }
34+
2935 static readonly Logger log = LogManager . GetCurrentClassLogger ( ) ;
3036 CompositeDisposable disposables = new CompositeDisposable ( ) ;
3137 readonly IServiceProvider serviceProvider ;
3238 CompositionContainer tempContainer ;
33- readonly Dictionary < string , ComposablePart > tempParts ;
39+ readonly Dictionary < string , OwnedComposablePart > tempParts ;
3440 ExportLifetimeContext < IUIController > currentUIFlow ;
3541 readonly Version currentVersion ;
3642 bool initializingLogging = false ;
@@ -72,7 +78,7 @@ public UIProvider([Import(typeof(SVsServiceProvider))] IServiceProvider serviceP
7278 {
7379 SourceProvider = ExportProvider
7480 } ) ) ;
75- tempParts = new Dictionary < string , ComposablePart > ( ) ;
81+ tempParts = new Dictionary < string , OwnedComposablePart > ( ) ;
7682 }
7783
7884 [ return : AllowNull ]
@@ -152,12 +158,12 @@ public Ret GetService<T, Ret>() where Ret : class
152158 return GetService < T > ( ) as Ret ;
153159 }
154160
155- public void AddService < T > ( T instance )
161+ public void AddService < T > ( object owner , T instance )
156162 {
157- AddService ( typeof ( T ) , instance ) ;
163+ AddService ( typeof ( T ) , owner , instance ) ;
158164 }
159165
160- public void AddService ( Type t , object instance )
166+ public void AddService ( Type t , object owner , object instance )
161167 {
162168 if ( ! Initialized )
163169 {
@@ -168,13 +174,23 @@ public void AddService(Type t, object instance)
168174 var batch = new CompositionBatch ( ) ;
169175 string contract = AttributedModelServices . GetContractName ( t ) ;
170176 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+
171181 var part = batch . AddExportedValue ( contract , instance ) ;
172182 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 } ) ;
174184 tempContainer . Compose ( batch ) ;
175185 }
176186
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 )
178194 {
179195 if ( ! Initialized )
180196 {
@@ -185,13 +201,14 @@ public void RemoveService(Type t)
185201 string contract = AttributedModelServices . GetContractName ( t ) ;
186202 Debug . Assert ( ! string . IsNullOrEmpty ( contract ) , "Every type must have a contract name" ) ;
187203
188- ComposablePart part ;
189-
204+ OwnedComposablePart part ;
190205 if ( tempParts . TryGetValue ( contract , out part ) )
191206 {
207+ if ( owner != null && part . Owner != owner )
208+ return ;
192209 tempParts . Remove ( contract ) ;
193210 var batch = new CompositionBatch ( ) ;
194- batch . RemovePart ( part ) ;
211+ batch . RemovePart ( part . Part ) ;
195212 tempContainer . Compose ( batch ) ;
196213 }
197214 }
0 commit comments