Skip to content
This repository
Browse code

Allow service registration using the AddInTree.

  • Loading branch information...
commit c559da33362e7e92d4c1128388b35efb192df7f0 1 parent 46a82c7
Daniel Grunwald dgrunwald authored

Showing 20 changed files with 166 additions and 117 deletions. Show diff stats Hide diff stats

  1. +4 2 src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.addin
  2. +1 1  src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchResultNode.cs
  3. +1 1  src/Main/Base/Project/Src/Editor/AvalonEdit/AvalonEditTextEditorAdapter.cs
  4. +38 66 src/Main/Base/Project/Src/Editor/IEditorControlService.cs
  5. +2 2 src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs
  6. +1 1  src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/ApplicationSettings.cs
  7. +1 1  src/Main/Base/Project/Src/Gui/Pads/AbstractConsolePad.cs
  8. +2 2 src/Main/Base/Project/Src/Gui/Pads/DefinitionViewPad.cs
  9. +2 2 src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs
  10. +1 1  src/Main/Base/Project/Src/Project/AbstractProject.cs
  11. +6 3 src/Main/Base/Project/Src/Services/SD.cs
  12. +4 4 src/Main/Base/Project/Src/Util/ExtensionMethods.cs
  13. +8 20 src/Main/Base/Project/Src/Util/ThreadSafeServiceContainer.cs
  14. +2 1  src/Main/Core/Project/ICSharpCode.Core.csproj
  15. +6 0 src/Main/Core/Project/Src/AddInTree/CoreStartup.cs
  16. +62 0 src/Main/Core/Project/Src/Services/FallbackServiceAttribute.cs
  17. +7 0 src/Main/Core/Project/Src/Services/LoggingService/ILoggingService.cs
  18. +7 0 src/Main/Core/Project/Src/Services/MessageService/IMessageService.cs
  19. +10 9 src/Main/Core/Project/Src/Services/{ServiceManager.cs → ServiceSingleton.cs}
  20. +1 1  src/Main/SharpDevelop/Sda/CallHelper.cs
6 src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.addin
@@ -9,6 +9,7 @@
9 9
10 10 <Runtime>
11 11 <Import assembly = ":ICSharpCode.AvalonEdit"/>
  12 + <Import assembly = ":ICSharpCode.SharpDevelop"/>
12 13 <Import assembly = "ICSharpCode.AvalonEdit.AddIn.dll">
13 14 <Doozer name="SyntaxMode" class="ICSharpCode.AvalonEdit.AddIn.SyntaxModeDoozer"/>
14 15 <Doozer name="ContextActionOptionPanel" class="ICSharpCode.AvalonEdit.AddIn.ContextActions.ContextActionOptionPanelDoozer"/>
@@ -29,8 +30,9 @@
29 30 <Include id="DefaultEditor" path="/SharpDevelop/ViewContent/TextEditor/ContextMenu"/>
30 31 </Path>
31 32
32   - <Path name = "/SharpDevelop/ViewContent/TextEditor/EditorControlService">
33   - <Class id="CodeEditorView" class="ICSharpCode.AvalonEdit.AddIn.AvalonEditorControlService"/>
  33 + <Path name = "/SharpDevelop/Services">
  34 + <Service id="ICSharpCode.SharpDevelop.Editor.IEditorControlService"
  35 + class="ICSharpCode.AvalonEdit.AddIn.AvalonEditorControlService"/>
34 36 </Path>
35 37
36 38 <!--
2  src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchResultNode.cs
@@ -56,7 +56,7 @@ protected override object CreateText()
56 56 LoggingService.Debug("Creating text for search result (" + location.Line + ", " + location.Column + ") ");
57 57
58 58 TextBlock textBlock = new TextBlock();
59   - textBlock.FontFamily = new FontFamily(EditorControlService.GlobalOptions.FontFamily);
  59 + textBlock.FontFamily = new FontFamily(SD.EditorControlService.GlobalOptions.FontFamily);
60 60
61 61 textBlock.Inlines.Add("(" + location.Line + ", " + location.Column + ")\t");
62 62
2  src/Main/Base/Project/Src/Editor/AvalonEdit/AvalonEditTextEditorAdapter.cs
@@ -41,7 +41,7 @@ public AvalonEditTextEditorAdapter(TextEditor textEditor)
41 41 public static TextEditor CreateAvalonEditInstance()
42 42 {
43 43 object editor;
44   - EditorControlService.CreateEditor(out editor);
  44 + SD.EditorControlService.CreateEditor(out editor);
45 45 if (!(editor is TextEditor))
46 46 throw new NotSupportedException("Expected text editor to be AvalonEdit");
47 47 return (TextEditor)editor;
104 src/Main/Base/Project/Src/Editor/IEditorControlService.cs
@@ -3,6 +3,8 @@
3 3
4 4 using System;
5 5 using ICSharpCode.AvalonEdit;
  6 +using ICSharpCode.Core;
  7 +using ICSharpCode.Core.Services;
6 8 using ICSharpCode.SharpDevelop.Editor.AvalonEdit;
7 9
8 10 namespace ICSharpCode.SharpDevelop.Editor
@@ -10,86 +12,56 @@ namespace ICSharpCode.SharpDevelop.Editor
10 12 /// <summary>
11 13 /// Allows creating new text editor instances and accessing the default text editor options.
12 14 /// </summary>
  15 + [FallbackService(typeof(EditorControlServiceFallback))]
13 16 public interface IEditorControlService
14 17 {
15 18 ITextEditor CreateEditor(out object control);
16 19 ITextEditorOptions GlobalOptions { get; }
17 20 }
18 21
19   - /// <summary>
20   - /// Allows creating new text editor instances and accessing the default text editor options.
21   - /// </summary>
22   - public static class EditorControlService
  22 + // Fallback if AvalonEdit.AddIn is not available (e.g. some unit tests)
  23 + sealed class EditorControlServiceFallback : IEditorControlService, ITextEditorOptions
23 24 {
24   - static readonly Lazy<IEditorControlService> instance = new Lazy<IEditorControlService>(
25   - delegate {
26   - // fetch IEditorControlService that's normally implemented in AvalonEdit.AddIn
27   - var node = Core.AddInTree.GetTreeNode("/SharpDevelop/ViewContent/TextEditor/EditorControlService", false);
28   - IEditorControlService ecs = null;
29   - if (node != null && node.Codons.Count > 0) {
30   - ecs = (IEditorControlService)node.BuildChildItem(node.Codons[0], null);
31   - }
32   - return ecs ?? new DummyService();
33   - }
34   - );
35   -
36   - public static IEditorControlService Instance {
37   - get { return instance.Value; }
  25 + public ITextEditorOptions GlobalOptions {
  26 + get { return this; }
38 27 }
39 28
40   - public static ITextEditor CreateEditor(out object control)
  29 + public ITextEditor CreateEditor(out object control)
41 30 {
42   - return Instance.CreateEditor(out control);
  31 + TextEditor avalonedit = new TextEditor();
  32 + control = avalonedit;
  33 + return new AvalonEditTextEditorAdapter(avalonedit);
43 34 }
44 35
45   - public static ITextEditorOptions GlobalOptions {
46   - get { return Instance.GlobalOptions; }
  36 + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged { add {} remove {} }
  37 +
  38 + public string IndentationString {
  39 + get { return "\t"; }
47 40 }
48 41
49   - // Fallback if AvalonEdit.AddIn is not available (e.g. some unit tests)
50   - sealed class DummyService : IEditorControlService, ITextEditorOptions
51   - {
52   - public ITextEditorOptions GlobalOptions {
53   - get { return this; }
54   - }
55   -
56   - public ITextEditor CreateEditor(out object control)
57   - {
58   - TextEditor avalonedit = new TextEditor();
59   - control = avalonedit;
60   - return new AvalonEditTextEditorAdapter(avalonedit);
61   - }
62   -
63   - public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged { add {} remove {} }
64   -
65   - public string IndentationString {
66   - get { return "\t"; }
67   - }
68   -
69   - public bool AutoInsertBlockEnd {
70   - get { return true; }
71   - }
72   -
73   - public bool ConvertTabsToSpaces {
74   - get { return false; }
75   - }
76   -
77   - public int IndentationSize {
78   - get { return 4; }
79   - }
80   -
81   - public int VerticalRulerColumn {
82   - get { return 120; }
83   - }
84   -
85   - public bool UnderlineErrors {
86   - get { return true; }
87   - }
88   -
89   - public string FontFamily {
90   - get {
91   - return "Consolas";
92   - }
  42 + public bool AutoInsertBlockEnd {
  43 + get { return true; }
  44 + }
  45 +
  46 + public bool ConvertTabsToSpaces {
  47 + get { return false; }
  48 + }
  49 +
  50 + public int IndentationSize {
  51 + get { return 4; }
  52 + }
  53 +
  54 + public int VerticalRulerColumn {
  55 + get { return 120; }
  56 + }
  57 +
  58 + public bool UnderlineErrors {
  59 + get { return true; }
  60 + }
  61 +
  62 + public string FontFamily {
  63 + get {
  64 + return "Consolas";
93 65 }
94 66 }
95 67 }
4 src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs
@@ -374,8 +374,8 @@ public void SaveFile(FileDescriptionTemplate newfile, string content, string bin
374 374 string parsedContent = StringParser.Parse(StringParser.Parse(content));
375 375
376 376 if (parsedContent != null) {
377   - if (EditorControlService.GlobalOptions.IndentationString != "\t") {
378   - parsedContent = parsedContent.Replace("\t", EditorControlService.GlobalOptions.IndentationString);
  377 + if (SD.EditorControlService.GlobalOptions.IndentationString != "\t") {
  378 + parsedContent = parsedContent.Replace("\t", SD.EditorControlService.GlobalOptions.IndentationString);
379 379 }
380 380 }
381 381
2  src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/ApplicationSettings.cs
@@ -131,7 +131,7 @@ void CreateManifest()
131 131 defaultManifest = r.ReadToEnd();
132 132 }
133 133 }
134   - defaultManifest = defaultManifest.Replace("\t", EditorControlService.GlobalOptions.IndentationString);
  134 + defaultManifest = defaultManifest.Replace("\t", SD.EditorControlService.GlobalOptions.IndentationString);
135 135 File.WriteAllText(manifestFile, defaultManifest, System.Text.Encoding.UTF8);
136 136 FileService.FireFileCreated(manifestFile, false);
137 137 }
2  src/Main/Base/Project/Src/Gui/Pads/AbstractConsolePad.cs
@@ -278,7 +278,7 @@ public ConsoleControl()
278 278
279 279 object tmp;
280 280
281   - this.editorAdapter = EditorControlService.CreateEditor(out tmp);
  281 + this.editorAdapter = SD.EditorControlService.CreateEditor(out tmp);
282 282
283 283 this.editor = (AvalonEdit.TextEditor)tmp;
284 284 this.editor.SetValue(Grid.ColumnProperty, 0);
4 src/Main/Base/Project/Src/Gui/Pads/DefinitionViewPad.cs
@@ -86,9 +86,9 @@ void OnParserUpdateStep(object sender, ParserUpdateStepEventArgs e)
86 86 Task<ResolveResult> ResolveAtCaretAsync(ParserUpdateStepEventArgs e)
87 87 {
88 88 IWorkbenchWindow window = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow;
89   - if (window == null) return null;
  89 + if (window == null) return Task.FromResult<ResolveResult>(null);
90 90 ITextEditorProvider provider = window.ActiveViewContent as ITextEditorProvider;
91   - if (provider == null) return null;
  91 + if (provider == null) return Task.FromResult<ResolveResult>(null);
92 92 ITextEditor editor = provider.TextEditor;
93 93
94 94 // e might be null when this is a manually triggered update
4 src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs
@@ -375,8 +375,8 @@ public IProject CreateProject(ProjectCreateInformation projectCreateInformation,
375 375 StreamWriter sr = new StreamWriter(File.Create(fileName), ParserService.DefaultFileEncoding);
376 376 string fileContent = StringParser.Parse(file.Content, new StringTagPair("ProjectName", projectCreateInformation.ProjectName), new StringTagPair("FileName", fileName));
377 377 fileContent = StringParser.Parse(fileContent);
378   - if (EditorControlService.GlobalOptions.IndentationString != "\t") {
379   - fileContent = fileContent.Replace("\t", EditorControlService.GlobalOptions.IndentationString);
  378 + if (SD.EditorControlService.GlobalOptions.IndentationString != "\t") {
  379 + fileContent = fileContent.Replace("\t", SD.EditorControlService.GlobalOptions.IndentationString);
380 380 }
381 381 sr.Write(fileContent);
382 382 sr.Close();
2  src/Main/Base/Project/Src/Project/AbstractProject.cs
@@ -596,7 +596,7 @@ public virtual void GenerateCodeFromCodeDom(System.CodeDom.CodeCompileUnit compi
596 596 options.BlankLinesBetweenMembers = AmbienceService.CodeGenerationProperties.Get("BlankLinesBetweenMembers", true);
597 597 options.BracingStyle = AmbienceService.CodeGenerationProperties.Get("StartBlockOnSameLine", true) ? "Block" : "C";
598 598 options.ElseOnClosing = AmbienceService.CodeGenerationProperties.Get("ElseOnClosing", true);
599   - options.IndentString = ICSharpCode.SharpDevelop.Editor.EditorControlService.GlobalOptions.IndentationString;
  599 + options.IndentString = SD.EditorControlService.GlobalOptions.IndentationString;
600 600 provider.GenerateCodeFromCompileUnit(compileUnit, writer, options);
601 601 } else {
602 602 writer.WriteLine("No CodeDom provider was found for this language.");
9 src/Main/Base/Project/Src/Services/SD.cs
@@ -6,6 +6,7 @@
6 6 using ICSharpCode.Core;
7 7 using ICSharpCode.Core.Implementation;
8 8 using ICSharpCode.Core.Services;
  9 +using ICSharpCode.SharpDevelop.Editor;
9 10 using ICSharpCode.SharpDevelop.Gui;
10 11
11 12 namespace ICSharpCode.SharpDevelop
@@ -32,9 +33,7 @@ public static class SD
32 33 /// </summary>
33 34 public static void InitializeForUnitTests()
34 35 {
35   - var container = new ThreadSafeServiceContainer();
36   - container.AddService(typeof(ILoggingService), new TextWriterLoggingService(new TraceTextWriter()));
37   - container.AddService(typeof(IMessageService), new TextWriterMessageService(Console.Out));
  36 + var container = new ThreadSafeServiceContainer(ServiceSingleton.FallbackServiceProvider);
38 37 PropertyService.InitializeServiceForUnitTests();
39 38 ServiceSingleton.ServiceProvider = container;
40 39 }
@@ -76,5 +75,9 @@ public static void InitializeForUnitTests()
76 75 public static IMessageService MessageService {
77 76 get { return GetRequiredService<IMessageService>(); }
78 77 }
  78 +
  79 + public static IEditorControlService EditorControlService {
  80 + get { return GetRequiredService<IEditorControlService>(); }
  81 + }
79 82 }
80 83 }
8 src/Main/Base/Project/Src/Util/ExtensionMethods.cs
@@ -519,9 +519,9 @@ public static XElement FormatXml(this XElement element, int indentationLevel)
519 519 {
520 520 StringWriter sw = new StringWriter();
521 521 using (XmlTextWriter xmlW = new XmlTextWriter(sw)) {
522   - if (EditorControlService.GlobalOptions.ConvertTabsToSpaces) {
  522 + if (SD.EditorControlService.GlobalOptions.ConvertTabsToSpaces) {
523 523 xmlW.IndentChar = ' ';
524   - xmlW.Indentation = EditorControlService.GlobalOptions.IndentationSize;
  524 + xmlW.Indentation = SD.EditorControlService.GlobalOptions.IndentationSize;
525 525 } else {
526 526 xmlW.Indentation = 1;
527 527 xmlW.IndentChar = '\t';
@@ -538,7 +538,7 @@ static string GetIndentation(int level)
538 538 {
539 539 StringBuilder indentation = new StringBuilder();
540 540 for (int i = 0; i < level; i++) {
541   - indentation.Append(EditorControlService.GlobalOptions.IndentationString);
  541 + indentation.Append(SD.EditorControlService.GlobalOptions.IndentationString);
542 542 }
543 543 return indentation.ToString();
544 544 }
@@ -573,7 +573,7 @@ public static XElement AddFirstWithIndentation(this XElement element, XElement n
573 573 while (tmp != null) {
574 574 tmp = tmp.Parent;
575 575 indentationLevel++;
576   - indentation.Append(EditorControlService.GlobalOptions.IndentationString);
  576 + indentation.Append(SD.EditorControlService.GlobalOptions.IndentationString);
577 577 }
578 578 if (!element.Nodes().Any()) {
579 579 element.Add(new XText(Environment.NewLine + GetIndentation(indentationLevel - 1)));
28 src/Main/Base/Project/Src/Util/ThreadSafeServiceContainer.cs
@@ -13,7 +13,8 @@ namespace ICSharpCode.SharpDevelop
13 13 /// </summary>
14 14 public class ThreadSafeServiceContainer : IServiceProvider, IServiceContainer, IDisposable
15 15 {
16   - Dictionary<Type, object> services = new Dictionary<Type, object>();
  16 + readonly IServiceProvider parentProvider;
  17 + readonly Dictionary<Type, object> services = new Dictionary<Type, object>();
17 18
18 19 public ThreadSafeServiceContainer()
19 20 {
@@ -21,33 +22,20 @@ public ThreadSafeServiceContainer()
21 22 services.Add(typeof(IServiceContainer), this);
22 23 }
23 24
24   - public object GetOrCreateService(Type type, Func<object> serviceCreator)
  25 + public ThreadSafeServiceContainer(IServiceProvider parentProvider) : this()
25 26 {
26   - lock (services) {
27   - object instance;
28   - if (!services.TryGetValue(type, out instance)) {
29   - instance = serviceCreator();
30   - services.Add(type, instance);
31   - }
32   - return instance;
33   - }
34   - }
35   -
36   - public void TryAddService(Type type, object instance)
37   - {
38   - lock (services) {
39   - if (!services.ContainsKey(type))
40   - services.Add(type, instance);
41   - }
  27 + this.parentProvider = parentProvider;
42 28 }
43 29
44 30 public object GetService(Type serviceType)
45 31 {
  32 + bool foundService;
46 33 object instance;
47 34 lock (services) {
48   - if (!services.TryGetValue(serviceType, out instance))
49   - return null;
  35 + foundService = services.TryGetValue(serviceType, out instance);
50 36 }
  37 + if (!foundService)
  38 + return parentProvider != null ? parentProvider.GetService(serviceType) : null;
51 39 ServiceCreatorCallback callback = instance as ServiceCreatorCallback;
52 40 if (callback == null)
53 41 return instance;
3  src/Main/Core/Project/ICSharpCode.Core.csproj
@@ -107,6 +107,7 @@
107 107 <Compile Include="Src\Services\AnalyticsMonitor\AnalyticsMonitorService.cs" />
108 108 <Compile Include="Src\Services\AnalyticsMonitor\IAnalyticsMonitor.cs" />
109 109 <Compile Include="Src\Services\ApplicationStateInfoService.cs" />
  110 + <Compile Include="Src\Services\FallbackServiceAttribute.cs" />
110 111 <Compile Include="Src\Services\FileUtility\FileName.cs" />
111 112 <Compile Include="Src\Services\FileUtility\FileNameEventHandler.cs" />
112 113 <Compile Include="Src\Services\FileUtility\FileUtility.cs" />
@@ -121,7 +122,7 @@
121 122 <Compile Include="Src\Services\RegistryService\RegistryService.cs" />
122 123 <Compile Include="Src\Services\ResourceService\ResourceNotFoundException.cs" />
123 124 <Compile Include="Src\Services\ResourceService\ResourceService.cs" />
124   - <Compile Include="Src\Services\ServiceManager.cs" />
  125 + <Compile Include="Src\Services\ServiceSingleton.cs" />
125 126 <Compile Include="Src\Services\ServiceNotFoundException.cs" />
126 127 <Compile Include="Src\Services\StringParser\IStringTagProvider.cs" />
127 128 <Compile Include="Src\Services\StringParser\PropertyObjectTagProvider.cs" />
6 src/Main/Core/Project/Src/AddInTree/CoreStartup.cs
@@ -3,6 +3,7 @@
3 3
4 4 using System;
5 5 using System.Collections.Generic;
  6 +using System.ComponentModel.Design;
6 7 using System.IO;
7 8
8 9 namespace ICSharpCode.Core
@@ -176,6 +177,11 @@ public void RunInitialization()
176 177 {
177 178 AddInTree.Load(addInFiles, disabledAddIns);
178 179
  180 + // perform service registration
  181 + var container = ServiceSingleton.ServiceProvider.GetService<IServiceContainer>();
  182 + if (container != null)
  183 + AddInTree.BuildItems<object>("/SharpDevelop/Services", container, false);
  184 +
179 185 // run workspace autostart commands
180 186 LoggingService.Info("Running autostart commands...");
181 187 foreach (ICommand command in AddInTree.BuildItems<ICommand>("/Workspace/Autostart", null, false)) {
62 src/Main/Core/Project/Src/Services/FallbackServiceAttribute.cs
... ... @@ -0,0 +1,62 @@
  1 +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
  2 +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
  3 +
  4 +using System;
  5 +using System.Collections.Generic;
  6 +
  7 +namespace ICSharpCode.Core
  8 +{
  9 + /// <summary>
  10 + /// Used on a service interface to indicate the default implementation.
  11 + /// </summary>
  12 + [AttributeUsage(AttributeTargets.Interface, Inherited=false)]
  13 + public class FallbackServiceAttribute : Attribute
  14 + {
  15 + readonly string assemblyQualifiedName;
  16 + readonly Type fallbackServiceType;
  17 +
  18 + public FallbackServiceAttribute(Type fallbackServiceType)
  19 + {
  20 + if (fallbackServiceType == null)
  21 + throw new ArgumentNullException("fallbackServiceType");
  22 + this.fallbackServiceType = fallbackServiceType;
  23 + }
  24 +
  25 + public FallbackServiceAttribute(string assemblyQualifiedName)
  26 + {
  27 + if (assemblyQualifiedName == null)
  28 + throw new ArgumentNullException("assemblyQualifiedName");
  29 + this.assemblyQualifiedName = assemblyQualifiedName;
  30 + }
  31 +
  32 + public string AssemblyQualifiedName {
  33 + get { return assemblyQualifiedName ?? fallbackServiceType.AssemblyQualifiedName; }
  34 + }
  35 +
  36 + public Type FallbackServiceType {
  37 + get { return fallbackServiceType ?? Type.GetType(assemblyQualifiedName); }
  38 + }
  39 + }
  40 +
  41 + sealed class FallbackServiceProvider : IServiceProvider
  42 + {
  43 + Dictionary<Type, object> fallbackServiceDict = new Dictionary<Type, object>();
  44 +
  45 + public object GetService(Type serviceType)
  46 + {
  47 + object instance;
  48 + lock (fallbackServiceDict) {
  49 + if (!fallbackServiceDict.TryGetValue(serviceType, out instance)) {
  50 + var attr = serviceType.GetCustomAttributes(typeof(FallbackServiceAttribute), false);
  51 + if (attr.Length == 1) {
  52 + instance = Activator.CreateInstance(((FallbackServiceAttribute)attr[0]).FallbackServiceType);
  53 + } else {
  54 + instance = null;
  55 + }
  56 + fallbackServiceDict.Add(serviceType, instance);
  57 + }
  58 + }
  59 + return instance;
  60 + }
  61 + }
  62 +}
7 src/Main/Core/Project/Src/Services/LoggingService/ILoggingService.cs
@@ -2,9 +2,11 @@
2 2 // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
3 3
4 4 using System;
  5 +using ICSharpCode.Core.Implementation;
5 6
6 7 namespace ICSharpCode.Core
7 8 {
  9 + [FallbackService(typeof(FallbackLoggingService))]
8 10 public interface ILoggingService
9 11 {
10 12 void Debug(object message);
@@ -26,4 +28,9 @@ public interface ILoggingService
26 28 bool IsErrorEnabled { get; }
27 29 bool IsFatalEnabled { get; }
28 30 }
  31 +
  32 + sealed class FallbackLoggingService : TextWriterLoggingService
  33 + {
  34 + public FallbackLoggingService() : base(new TraceTextWriter()) {}
  35 + }
29 36 }
7 src/Main/Core/Project/Src/Services/MessageService/IMessageService.cs
@@ -2,12 +2,14 @@
2 2 // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
3 3
4 4 using System;
  5 +using ICSharpCode.Core.Implementation;
5 6
6 7 namespace ICSharpCode.Core
7 8 {
8 9 /// <summary>
9 10 /// Interface for the MessageService.
10 11 /// </summary>
  12 + [FallbackService(typeof(FallbackMessageService))]
11 13 public interface IMessageService
12 14 {
13 15 /// <summary>
@@ -62,6 +64,11 @@ public interface IMessageService
62 64 ChooseSaveErrorResult ChooseSaveError(string fileName, string message, string dialogName, Exception exceptionGot, bool chooseLocationEnabled);
63 65 }
64 66
  67 + sealed class FallbackMessageService : TextWriterMessageService
  68 + {
  69 + public FallbackMessageService() : base(Console.Out) {}
  70 + }
  71 +
65 72 public sealed class ChooseSaveErrorResult
66 73 {
67 74 public bool IsRetry { get; private set; }
19 src/Main/Core/Project/Src/Services/ServiceManager.cs → ...ain/Core/Project/Src/Services/ServiceSingleton.cs
@@ -6,6 +6,7 @@
6 6 using System.Collections.ObjectModel;
7 7 using System.ComponentModel.Design;
8 8 using ICSharpCode.Core.Implementation;
  9 +using ICSharpCode.Core.Services;
9 10
10 11 namespace ICSharpCode.Core
11 12 {
@@ -14,7 +15,15 @@ namespace ICSharpCode.Core
14 15 /// </summary>
15 16 public static class ServiceSingleton
16 17 {
17   - volatile static IServiceProvider instance = CreateDefaultServiceContainer();
  18 + static readonly IServiceProvider fallbackServiceProvider = new FallbackServiceProvider();
  19 + volatile static IServiceProvider instance = new ServiceContainer(fallbackServiceProvider);
  20 +
  21 + /// <summary>
  22 + /// Gets the service provider that provides the fallback services.
  23 + /// </summary>
  24 + public static IServiceProvider FallbackServiceProvider {
  25 + get { return fallbackServiceProvider; }
  26 + }
18 27
19 28 /// <summary>
20 29 /// Gets the static ServiceManager instance.
@@ -28,14 +37,6 @@ public static class ServiceSingleton
28 37 }
29 38 }
30 39
31   - static IServiceProvider CreateDefaultServiceContainer()
32   - {
33   - ServiceContainer container = new ServiceContainer();
34   - container.AddService(typeof(ILoggingService), new TextWriterLoggingService(new TraceTextWriter()));
35   - container.AddService(typeof(IMessageService), new TextWriterMessageService(Console.Out));
36   - return container;
37   - }
38   -
39 40 public static T GetService<T>(this IServiceProvider provider) where T : class
40 41 {
41 42 return (T)provider.GetService(typeof(T));
2  src/Main/SharpDevelop/Sda/CallHelper.cs
@@ -38,7 +38,7 @@ public override object InitializeLifetimeService()
38 38 public void InitSharpDevelopCore(SharpDevelopHost.CallbackHelper callback, StartupSettings properties)
39 39 {
40 40 // Initialize the most important services:
41   - var container = new ThreadSafeServiceContainer();
  41 + var container = new ThreadSafeServiceContainer(ServiceSingleton.FallbackServiceProvider);
42 42 container.AddService(typeof(IMessageService), new SDMessageService());
43 43 container.AddService(typeof(ILoggingService), new log4netLoggingService());
44 44 ServiceSingleton.ServiceProvider = container;

0 comments on commit c559da3

Please sign in to comment.
Something went wrong with that request. Please try again.