Do

Merge lp:~cszikszoy/do/newdo-service-loading into lp:do/rewrite

Proposed by Chris S.
Status: Work in progress
Proposed branch: lp:~cszikszoy/do/newdo-service-loading
Merge into: lp:do/rewrite
Diff against target: 354 lines (+225/-32)
7 files modified
src/Backends/DBus/DBus.csproj (+3/-0)
src/Core/Base/Base.csproj (+2/-0)
src/Core/Base/src/Addins.cs (+130/-0)
src/Core/Base/src/ServiceManager.cs (+73/-31)
src/Core/Base/src/UniverseManager.cs (+1/-1)
src/Core/Services/Resources/Do.Services.addin.xml (+9/-0)
src/Core/Services/Services.csproj (+7/-0)
To merge this branch: bzr merge lp:~cszikszoy/do/newdo-service-loading
Reviewer Review Type Date Requested Status
Alex Launi Needs Fixing
Review via email: mp+33493@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Alex Launi (alexlauni) wrote :

1.) Please comment all classes to say overall what the class is for. Give a little design intro as to the reason for the class. If you think it's abundantly obvious make it short, but have a little something
1a.) What's the point of the Addins class? What is in there that should not just be in ServiceManager? If you think that the Actual Mono.Addins stuff should be its own class (which I think I agree with) then try and take the AddinManager calls out of Services and fully abstract it out.
2.)
+ try {
+ AddinManager.Initialize (pluginsPath);
+ } catch (Exception e) {
+ AddinManager.Registry.Rebuild (monitor);
+ AddinManager.Shutdown ();
+ AddinManager.Initialize (pluginsPath);
+ }
+
+ AddinManager.Registry.Update (monitor);

Why wouldn't the 2nd call to AddinManager throw the same exception the first one did? Why do you Rebuild, shutdown, and then initialize? Is it necessary to Update after the Rebuild, Shutdown, Init cycle? The Update seems needless. If there's a good reason for this please put it into a comment so that this is clearer.
3.) Why does the DBus csproj need a Mono.Addins reference?
4.) Use Hyena.Log class for logging.

review: Needs Fixing

Unmerged revisions

15. By Chris S.

lay the groundwork for loading of services via mono.addins

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Backends/DBus/DBus.csproj'
2--- src/Backends/DBus/DBus.csproj 2010-08-23 00:27:07 +0000
3+++ src/Backends/DBus/DBus.csproj 2010-08-24 06:58:42 +0000
4@@ -47,6 +47,9 @@
5 <Reference Include="nunit.framework, Version=2.4.7.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
6 <Package>nunit</Package>
7 </Reference>
8+ <Reference Include="Mono.Addins, Version=0.4.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
9+ <Package>mono-addins</Package>
10+ </Reference>
11 </ItemGroup>
12 <ItemGroup>
13 <ProjectReference Include="..\..\Core\Services\Services.csproj">
14
15=== modified file 'src/Core/Base/Base.csproj'
16--- src/Core/Base/Base.csproj 2010-08-22 23:25:06 +0000
17+++ src/Core/Base/Base.csproj 2010-08-24 06:58:42 +0000
18@@ -40,6 +40,7 @@
19 <Reference Include="Hyena, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
20 <SpecificVersion>False</SpecificVersion>
21 <HintPath>..\..\..\..\..\..\..\..\..\usr\local\lib\hyena\Hyena.dll</HintPath>
22+ <Package>banshee-1-hyena</Package>
23 </Reference>
24 </ItemGroup>
25 <ItemGroup>
26@@ -58,6 +59,7 @@
27 <ItemGroup>
28 <Compile Include="src\ServiceManager.cs" />
29 <Compile Include="src\UniverseManager.cs" />
30+ <Compile Include="src\Addins.cs" />
31 </ItemGroup>
32 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
33 </Project>
34\ No newline at end of file
35
36=== added file 'src/Core/Base/src/Addins.cs'
37--- src/Core/Base/src/Addins.cs 1970-01-01 00:00:00 +0000
38+++ src/Core/Base/src/Addins.cs 2010-08-24 06:58:42 +0000
39@@ -0,0 +1,130 @@
40+//
41+// AddinManager.cs
42+//
43+// Author:
44+// Chris Szikszoy <chris@szikszoy.com>
45+//
46+// Copyright (c) 2010 Do developers
47+//
48+// This program is free software: you can redistribute it and/or modify
49+// it under the terms of the GNU General Public License as published by
50+// the Free Software Foundation, either version 3 of the License, or
51+// (at your option) any later version.
52+//
53+// This program is distributed in the hope that it will be useful,
54+// but WITHOUT ANY WARRANTY; without even the implied warranty of
55+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56+// GNU General Public License for more details.
57+//
58+// You should have received a copy of the GNU General Public License
59+// along with this program. If not, see <http://www.gnu.org/licenses/>.
60+
61+using System;
62+using System.Linq;
63+using System.Collections.Generic;
64+
65+using Mono.Addins;
66+using Hyena;
67+
68+namespace Do
69+{
70+ public class AddinStateChangedEventArgs : EventArgs
71+ {
72+ public Addin Addin { get; private set; }
73+
74+ public AddinStateChangedEventArgs (Addin addin)
75+ {
76+ Addin = addin;
77+ }
78+ }
79+
80+ public class Addins
81+ {
82+ static Addins ()
83+ {
84+ }
85+
86+ #region public api
87+
88+ public static event EventHandler<AddinStateChangedEventArgs> AddinStateChanged;
89+
90+ public static void Initialize ()
91+ {
92+ string pluginsPath = ApplicationContext.CommandLine.Contains ("uninstalled")
93+ ? "." : Paths.ApplicationData;
94+ IProgressStatus monitor = ApplicationContext.CommandLine.Contains ("debug-addins")
95+ ? new ConsoleProgressStatus (true)
96+ : null;
97+
98+ try {
99+ AddinManager.Initialize (pluginsPath);
100+ } catch (Exception e) {
101+ AddinManager.Registry.Rebuild (monitor);
102+ AddinManager.Shutdown ();
103+ AddinManager.Initialize (pluginsPath);
104+ }
105+
106+ AddinManager.Registry.Update (monitor);
107+
108+ // Add feedback when addin is loaded or unloaded
109+ AddinManager.AddinLoaded += AddinManagerAddinLoaded;
110+ AddinManager.AddinUnloaded += AddinManagerAddinUnloaded;
111+ }
112+
113+ /// <summary>
114+ /// All addins in the Addins registry.
115+ /// </summary>
116+ public static IEnumerable<Addin> AllAddins {
117+ get {
118+ return AddinManager.Registry.GetAddins ();
119+ }
120+ }
121+
122+ #endregion
123+
124+ static void OnStateChanged (Addin addin)
125+ {
126+ if (AddinStateChanged != null)
127+ AddinStateChanged (null, new AddinStateChangedEventArgs (addin));
128+ }
129+
130+ static void AddinManagerAddinLoaded (object sender, AddinEventArgs args)
131+ {
132+ Addin addin = AddinFromID (args.AddinId);
133+ OnStateChanged (addin);
134+ //Log<PluginManager>.Info ("Loaded \"{0}\".", addin.Name);
135+ }
136+
137+ static void AddinManagerAddinUnloaded (object sender, AddinEventArgs args)
138+ {
139+ Addin addin = AddinFromID (args.AddinId);
140+ OnStateChanged (addin);
141+ //Log<PluginManager>.Info ("Unloaded \"{0}\".", addin.Name);
142+ }
143+
144+ /// <summary>
145+ /// Look up an addin by supplying the Addin ID.
146+ /// </summary>
147+ /// <param name="id">
148+ /// A <see cref="System.String"/>
149+ /// </param>
150+ /// <returns>
151+ /// A <see cref="Addin"/>
152+ /// </returns>
153+ public static Addin AddinFromID (string id)
154+ {
155+ return AddinManager.Registry.GetAddin (id);
156+ }
157+
158+ static T ObjectFromAddin<T> (string extensionPath, string addinID) where T : class
159+ {
160+ IEnumerable<TypeExtensionNode> nodes = AddinManager.GetExtensionNodes (extensionPath)
161+ .OfType<TypeExtensionNode> ()
162+ .Where (a => Addin.GetIdName (a.Addin.Id) == Addin.GetIdName (addinID));
163+
164+ if (nodes.Any ())
165+ return nodes.First ().GetInstance () as T;
166+ return null;
167+ }
168+ }
169+}
170
171=== modified file 'src/Core/Base/src/ServiceManager.cs'
172--- src/Core/Base/src/ServiceManager.cs 2010-08-22 23:25:06 +0000
173+++ src/Core/Base/src/ServiceManager.cs 2010-08-24 06:58:42 +0000
174@@ -20,6 +20,7 @@
175 // along with this program. If not, see <http://www.gnu.org/licenses/>.
176
177 using System;
178+using System.Linq;
179 using System.Collections.Generic;
180
181 using Mono.Addins;
182@@ -28,47 +29,88 @@
183 using Do.Services;
184
185 namespace Do
186-{
187+{
188 /// <summary>
189 /// Loads, and unloads the services that make Do run.
190 /// Three cheers for the service manager, all man right here.
191 /// </summary>
192 public class ServiceManager
193 {
194- public ServiceManager ()
195- {
196- InitializeAddins ();
197+
198+ public static UniverseManager universe;
199+
200+ static ServiceManager ()
201+ {
202+ }
203+
204+ #region public API
205+
206+ /// <summary>
207+ /// Initializes the service manager, builds (or rebuilds) the addin registry and registers the services
208+ /// </summary>
209+ public static void Initialize ()
210+ {
211+ Addins.Initialize ();
212+
213+ AddinManager.AddExtensionNodeHandler ("/Do/Service", OnServiceChanged);
214+
215 RegisterDefaultServices ();
216 RegisterServiceAddins ();
217 }
218-
219- void InitializeAddins ()
220- {
221- AddinManager.Initialize (ApplicationContext.CommandLine.Contains ("uninstalled")
222- ? "." : Paths.ApplicationData);
223-
224- IProgressStatus monitor = ApplicationContext.CommandLine.Contains ("debug-addins")
225- ? new ConsoleProgressStatus (true)
226- : null;
227-
228- if (ApplicationContext.Debugging) {
229- AddinManager.Registry.Rebuild (monitor);
230- } else {
231- AddinManager.Registry.Update (monitor);
232- }
233- }
234-
235- void RegisterServiceAddins ()
236- {
237- }
238-
239- void RegisterDefaultServices ()
240- {
241- }
242-
243- void RegisterService (IService service)
244+
245+ #region public services
246+
247+ public static UniverseManager Universe {
248+ get {
249+ if (universe == null) {
250+ IIpcUniverseProxy proxy = LoadService<IIpcUniverseProxy> ();
251+ universe = new UniverseManager (proxy);
252+ }
253+ return universe;
254+ }
255+ }
256+
257+ #endregion
258+
259+ #endregion
260+
261+ static void OnServiceChanged (object sender, ExtensionNodeEventArgs e)
262+ {
263+ IService service = e.ExtensionObject as IService;
264+
265+ switch (e.Change) {
266+ case ExtensionChange.Add:
267+ if (service is IInitializedService)
268+ (service as IInitializedService).Initialize ();
269+ break;
270+ case ExtensionChange.Remove:
271+ break;
272+ }
273+
274+ if (service is IIpcUniverseProxy)
275+ universe = null;
276+ }
277+
278+ static TService LoadService<TService> () where TService : class, IService
279+ {
280+ TService [] extensionObjects = AddinManager.GetExtensionObjects ("/Do/Service", true).OfType<TService> ();
281+
282+ //FIXME: with logging framework...
283+ /*
284+ if (!extensionObjects.Any ())
285+ fatal... ("no services of type TService found...")
286+ if (extensionObjects.Count () > 1)
287+ warn... ("more than 1 service of type TService found... only using the first")
288+ */
289+ return extensionObjects.First ();
290+ }
291+
292+ static void RegisterServiceAddins ()
293+ {
294+ }
295+
296+ static void RegisterDefaultServices ()
297 {
298 }
299 }
300 }
301-
302
303=== modified file 'src/Core/Base/src/UniverseManager.cs'
304--- src/Core/Base/src/UniverseManager.cs 2010-08-23 00:27:07 +0000
305+++ src/Core/Base/src/UniverseManager.cs 2010-08-24 06:58:42 +0000
306@@ -40,7 +40,7 @@
307 /// A <see cref="IIpcUniverseManager"/> proxy to the IPC service
308 /// that sources actually talk to.
309 /// </param>
310- public UniverseManager (IIpcUniverseProxy proxy)
311+ internal UniverseManager (IIpcUniverseProxy proxy)
312 {
313 }
314
315
316=== added directory 'src/Core/Services/Resources'
317=== added file 'src/Core/Services/Resources/Do.Services.addin.xml'
318--- src/Core/Services/Resources/Do.Services.addin.xml 1970-01-01 00:00:00 +0000
319+++ src/Core/Services/Resources/Do.Services.addin.xml 2010-08-24 06:58:42 +0000
320@@ -0,0 +1,9 @@
321+<Addin id="Services" namespace="Do" version="1.0" isroot="true">
322+ <Runtime>
323+ <Import assembly="Do.Services.dll"/>
324+ </Runtime>
325+
326+ <ExtensionPoint path="/Do/Service">
327+ <ExtensionNode name="Service" objectType="Do.Services.IService"/>
328+ </ExtensionPoint>
329+</Addin>
330
331=== modified file 'src/Core/Services/Services.csproj'
332--- src/Core/Services/Services.csproj 2010-08-23 00:27:07 +0000
333+++ src/Core/Services/Services.csproj 2010-08-24 06:58:42 +0000
334@@ -35,6 +35,9 @@
335 <ItemGroup>
336 <Reference Include="System" />
337 <Reference Include="System.Core" />
338+ <Reference Include="Mono.Addins, Version=0.4.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756">
339+ <Package>mono-addins</Package>
340+ </Reference>
341 </ItemGroup>
342 <ItemGroup>
343 <Compile Include="src\IExportable.cs" />
344@@ -44,5 +47,9 @@
345 </ItemGroup>
346 <ItemGroup>
347 <Folder Include="src\" />
348+ <Folder Include="Resources\" />
349+ </ItemGroup>
350+ <ItemGroup>
351+ <None Include="Resources\Do.Services.addin.xml" />
352 </ItemGroup>
353 </Project>
354\ No newline at end of file

Subscribers

People subscribed via source and target branches

to all changes: