Browse Source

AnalyticsMonitorService: move to new services infrastructure

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
d38eb13e71
  1. 2
      SharpDevelop.Tests.sln
  2. 3
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpContextActionWrapper.cs
  3. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs
  4. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs
  5. 7
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/NewLineConsistencyCheck.cs
  6. 4
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs
  7. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs
  8. 6
      src/AddIns/DisplayBindings/HexEditor/Project/Src/View/HexEditView.cs
  9. 20
      src/AddIns/Misc/UsageDataCollector/UsageDataCollector.AddIn/AnalyticsMonitor.cs
  10. 2
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  11. 2
      src/Main/Base/Project/Src/Bookmarks/EntityBookmark.cs
  12. 1
      src/Main/Base/Project/Src/Editor/IEditorControlService.cs
  13. 1
      src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs
  14. 10
      src/Main/Base/Project/Src/Project/BuildEngine.cs
  15. 2
      src/Main/Base/Project/Src/Project/Converter/UpgradeView.xaml.cs
  16. 2
      src/Main/Base/Project/Src/Project/Converter/UpgradeViewContent.cs
  17. 2
      src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs
  18. 7
      src/Main/Base/Project/Src/Services/SD.cs
  19. 58
      src/Main/Base/Project/Src/Util/SharpDevelopServiceContainer.cs
  20. 4
      src/Main/Core/Project/ICSharpCode.Core.csproj
  21. 6
      src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs
  22. 7
      src/Main/Core/Project/Src/AddInTree/AddIn/Runtime.cs
  23. 98
      src/Main/Core/Project/Src/Services/AnalyticsMonitor/AnalyticsMonitorService.cs
  24. 17
      src/Main/Core/Project/Src/Services/AnalyticsMonitor/IAnalyticsMonitor.cs
  25. 67
      src/Main/Core/Project/Src/Services/AnalyticsMonitorService.cs
  26. 1
      src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs
  27. 1
      src/Main/Core/Project/Src/Services/LoggingService/LoggingService.cs
  28. 1
      src/Main/Core/Project/Src/Services/MessageService/MessageService.cs
  29. 1
      src/Main/Core/Project/Src/Services/ServiceSingleton.cs
  30. 4
      src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
  31. 2
      src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs
  32. 2
      src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs
  33. 2
      src/Main/ICSharpCode.Core.WinForms/MessageService/IDialogMessageService.cs
  34. 2
      src/Main/ICSharpCode.Core.WinForms/MessageService/WinFormsMessageService.cs
  35. 2
      src/Main/ICSharpCode.Core.WinForms/ToolBar/ToolBarCommand.cs
  36. 2
      src/Main/SharpDevelop/Gui/Workbench/AvalonDockLayout.cs
  37. 2
      src/Main/SharpDevelop/Logging/ExceptionBox.cs
  38. 1
      src/Main/SharpDevelop/Logging/SDMessageService.cs
  39. 1
      src/Main/SharpDevelop/Logging/log4netLoggingService.cs
  40. 3
      src/Main/SharpDevelop/Sda/CallHelper.cs
  41. 2
      src/Main/SharpDevelop/app.template.config

2
SharpDevelop.Tests.sln

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.2.0.8695-Beta 2
# SharpDevelop 4.2.0.8707-Beta 2
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{256F5C28-532C-44C0-8AB8-D8EC5E492E01}"
ProjectSection(SolutionItems) = postProject
EndProjectSection

3
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpContextActionWrapper.cs

@ -12,6 +12,7 @@ using ICSharpCode.Core; @@ -12,6 +12,7 @@ using ICSharpCode.Core;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Refactoring;
@ -48,7 +49,7 @@ namespace CSharpBinding.Refactoring @@ -48,7 +49,7 @@ namespace CSharpBinding.Refactoring
public void Execute(EditorRefactoringContext context)
{
AnalyticsMonitorService.TrackFeature(provider.ID);
SD.AnalyticsMonitor.TrackFeature(provider.ID);
var resolver = context.GetAstResolverAsync().Result;
var refactoringContext = new SDRefactoringContext(context.Editor, resolver, context.CaretLocation);
var action = getUpdatedCodeAction(refactoringContext);

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs

@ -44,7 +44,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -44,7 +44,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
string filetype = Path.GetExtension(file.FileName);
if (!ProjectService.GetFileFilters().Any(f => f.ContainsExtension(filetype)))
filetype = ".?";
trackedFeature = AnalyticsMonitorService.TrackFeature(typeof(AvalonEditViewContent), "open" + filetype.ToLowerInvariant());
trackedFeature = SD.AnalyticsMonitor.TrackFeature(typeof(AvalonEditViewContent), "open" + filetype.ToLowerInvariant());
}
this.Files.Add(file);

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs

@ -487,7 +487,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -487,7 +487,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
var position = GetPositionFromPoint(e.GetPosition(this));
if (position == null)
return;
Core.AnalyticsMonitorService.TrackFeature(typeof(GoToDefinition).FullName, "Ctrl+Click");
SD.AnalyticsMonitor.TrackFeature(typeof(GoToDefinition).FullName, "Ctrl+Click");
var goToDefinitionCommand = new GoToDefinition();
goToDefinitionCommand.Run(this.Adapter, this.Document.GetOffset(position.Value.Location));
e.Handled = true;

7
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/NewLineConsistencyCheck.cs

@ -8,6 +8,7 @@ using System.Windows.Controls; @@ -8,6 +8,7 @@ using System.Windows.Controls;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.SharpDevelop;
namespace ICSharpCode.AvalonEdit.AddIn
{
@ -115,7 +116,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -115,7 +116,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
};
editor.Children.Add(groupBox);
var featureUse = AnalyticsMonitorService.TrackFeature(typeof(NewLineConsistencyCheck));
var featureUse = SD.AnalyticsMonitor.TrackFeature(typeof(NewLineConsistencyCheck));
EventHandler removeWarning = null;
removeWarning = delegate {
@ -128,11 +129,11 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -128,11 +129,11 @@ namespace ICSharpCode.AvalonEdit.AddIn
editor.LoadedFileContent += removeWarning;
cancelButton.Click += delegate {
AnalyticsMonitorService.TrackFeature(typeof(NewLineConsistencyCheck), "cancelButton");
SD.AnalyticsMonitor.TrackFeature(typeof(NewLineConsistencyCheck), "cancelButton");
removeWarning(null, null);
};
normalizeButton.Click += delegate {
AnalyticsMonitorService.TrackFeature(typeof(NewLineConsistencyCheck), "normalizeButton");
SD.AnalyticsMonitor.TrackFeature(typeof(NewLineConsistencyCheck), "normalizeButton");
removeWarning(null, null);
TextDocument document = editor.Document;

4
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs

@ -255,7 +255,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -255,7 +255,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
}
memberItems.Sort();
if (jumpOnSelectionChange) {
AnalyticsMonitorService.TrackFeature(GetType(), "JumpToClass");
SD.AnalyticsMonitor.TrackFeature(GetType(), "JumpToClass");
JumpTo(item, selectedClass.Region);
}
}
@ -269,7 +269,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -269,7 +269,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
if (item != null) {
IMember member = item.Entity as IMember;
if (member != null && jumpOnSelectionChange) {
AnalyticsMonitorService.TrackFeature(GetType(), "JumpToMember");
SD.AnalyticsMonitor.TrackFeature(GetType(), "JumpToMember");
JumpTo(item, member.Region);
}
}

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs

@ -264,7 +264,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets @@ -264,7 +264,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
internal void TrackUsage(string activationMethod)
{
bool isUserModified = !SnippetManager.defaultSnippets.Any(g => g.Snippets.Contains(this));
Core.AnalyticsMonitorService.TrackFeature(typeof(CodeSnippet), isUserModified ? "usersnippet" : Name, activationMethod);
SD.AnalyticsMonitor.TrackFeature(typeof(CodeSnippet), isUserModified ? "usersnippet" : Name, activationMethod);
}
}
}

6
src/AddIns/DisplayBindings/HexEditor/Project/Src/View/HexEditView.cs

@ -23,7 +23,7 @@ namespace HexEditor.View @@ -23,7 +23,7 @@ namespace HexEditor.View
file.ForceInitializeView(this);
AnalyticsMonitorService.TrackFeature(typeof(HexEditView));
SD.AnalyticsMonitor.TrackFeature(typeof(HexEditView));
}
public override object Control {
@ -32,7 +32,7 @@ namespace HexEditor.View @@ -32,7 +32,7 @@ namespace HexEditor.View
public override void Save(OpenedFile file, Stream stream)
{
AnalyticsMonitorService.TrackFeature(typeof(HexEditView), "Save");
SD.AnalyticsMonitor.TrackFeature(typeof(HexEditView), "Save");
this.hexEditContainer.SaveFile(file, stream);
this.TitleName = Path.GetFileName(file.FileName);
this.TabPageText = this.TitleName;
@ -40,7 +40,7 @@ namespace HexEditor.View @@ -40,7 +40,7 @@ namespace HexEditor.View
public override void Load(OpenedFile file, Stream stream)
{
AnalyticsMonitorService.TrackFeature(typeof(HexEditView), "Load");
SD.AnalyticsMonitor.TrackFeature(typeof(HexEditView), "Load");
this.hexEditContainer.LoadFile(file, stream);
}

20
src/AddIns/Misc/UsageDataCollector/UsageDataCollector.AddIn/AnalyticsMonitor.cs

@ -9,7 +9,6 @@ using System.Linq; @@ -9,7 +9,6 @@ using System.Linq;
using System.Threading;
using System.Windows.Media;
using ICSharpCode.Core;
using ICSharpCode.Core.Services;
using ICSharpCode.SharpDevelop;
using ICSharpCode.UsageDataCollector.Contracts;
@ -18,7 +17,7 @@ namespace ICSharpCode.UsageDataCollector @@ -18,7 +17,7 @@ namespace ICSharpCode.UsageDataCollector
/// <summary>
/// Main singleton class of the analytics. This class is thread-safe.
/// </summary>
public sealed partial class AnalyticsMonitor : IAnalyticsMonitor
public sealed partial class AnalyticsMonitor : IAnalyticsMonitor, IDisposable
{
const string UploadUrl = "http://usagedatacollector.sharpdevelop.net/upload/UploadUsageData.svc";
const string ProductName = "sharpdevelop";
@ -28,7 +27,7 @@ namespace ICSharpCode.UsageDataCollector @@ -28,7 +27,7 @@ namespace ICSharpCode.UsageDataCollector
public static bool EnabledIsUndecided {
get {
return PropertyService.Contains("ICSharpCode.UsageDataCollector.Enabled");
return !PropertyService.Contains("ICSharpCode.UsageDataCollector.Enabled");
}
}
@ -66,8 +65,11 @@ namespace ICSharpCode.UsageDataCollector @@ -66,8 +65,11 @@ namespace ICSharpCode.UsageDataCollector
{
SD.Services.AddService(typeof(IAnalyticsMonitor), this);
dbFileName = Path.Combine(PropertyService.ConfigDirectory, "usageData.dat");
}
SharpDevelop.Gui.WorkbenchSingleton.WorkbenchUnloaded += delegate { CloseSession(); };
void IDisposable.Dispose()
{
CloseSession();
}
static Guid FindUserId()
@ -214,6 +216,16 @@ namespace ICSharpCode.UsageDataCollector @@ -214,6 +216,16 @@ namespace ICSharpCode.UsageDataCollector
}
}
public IAnalyticsMonitorTrackedFeature TrackFeature(Type featureClass, string featureName = null, string activationMethod = null)
{
if (featureClass == null)
throw new ArgumentNullException("featureClass");
if (featureName != null)
return TrackFeature(featureClass.FullName + "/" + featureName, activationMethod);
else
return TrackFeature(featureClass.FullName, activationMethod);
}
public IAnalyticsMonitorTrackedFeature TrackFeature(string featureName, string activationMethod)
{
TrackedFeature feature = new TrackedFeature();

2
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -735,6 +735,7 @@ @@ -735,6 +735,7 @@
<Compile Include="Src\Util\DotnetDetection.cs" />
<Compile Include="Src\Util\FakeXmlViewContent.cs" />
<Compile Include="Src\Util\ReactiveExtensions.cs" />
<Compile Include="Src\Util\SharpDevelopServiceContainer.cs" />
<Compile Include="Src\Util\TreeNode.cs" />
<Compile Include="Src\Util\NativeMethods.cs" />
<Compile Include="Src\Util\ProcessRunnerException.cs" />
@ -780,7 +781,6 @@ @@ -780,7 +781,6 @@
<Compile Include="Src\Project\BuildTarget.cs" />
<Compile Include="Src\Util\GenericConverter.cs" />
<Compile Include="Src\Internal\Templates\TemplateLoadException.cs" />
<Compile Include="Src\Util\ThreadSafeServiceContainer.cs" />
<Compile Include="Src\Util\UnclosableStream.cs" />
<Compile Include="Src\Util\WeakCollection.cs" />
<Compile Include="Src\Util\WindowsFormsPrinting.cs" />

2
src/Main/Base/Project/Src/Bookmarks/EntityBookmark.cs

@ -54,7 +54,7 @@ namespace ICSharpCode.SharpDevelop.Bookmarks @@ -54,7 +54,7 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
public virtual void MouseDown(MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left) {
var f = AnalyticsMonitorService.TrackFeature("ICSharpCode.SharpDevelop.Bookmarks.EntityBookmark.ShowContextMenu");
var f = SD.AnalyticsMonitor.TrackFeature("ICSharpCode.SharpDevelop.Bookmarks.EntityBookmark.ShowContextMenu");
var ctx = MenuService.ShowContextMenu(e.Source as UIElement, entity, ContextMenuPath);
ctx.Closed += delegate { f.EndTracking(); };
e.Handled = true;

1
src/Main/Base/Project/Src/Editor/IEditorControlService.cs

@ -4,7 +4,6 @@ @@ -4,7 +4,6 @@
using System;
using ICSharpCode.AvalonEdit;
using ICSharpCode.Core;
using ICSharpCode.Core.Services;
using ICSharpCode.SharpDevelop.Editor.AvalonEdit;
namespace ICSharpCode.SharpDevelop.Editor

1
src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs

@ -10,7 +10,6 @@ using System.Linq; @@ -10,7 +10,6 @@ using System.Linq;
using System.Text;
using System.Windows.Forms;
using ICSharpCode.Core;
using ICSharpCode.Core.Services;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui.XmlForms;

10
src/Main/Base/Project/Src/Project/BuildEngine.cs

@ -41,7 +41,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -41,7 +41,7 @@ namespace ICSharpCode.SharpDevelop.Project
WorkbenchSingleton.AssertMainThread();
if (guiBuildCancellation != null) {
BuildResults results = new BuildResults();
WorkbenchSingleton.StatusBar.SetMessage(Core.ResourceService.GetString("MainWindow.CompilerMessages.MSBuildAlreadyRunning"));
SD.StatusBar.SetMessage(Core.ResourceService.GetString("MainWindow.CompilerMessages.MSBuildAlreadyRunning"));
BuildError error = new BuildError(null, Core.ResourceService.GetString("MainWindow.CompilerMessages.MSBuildAlreadyRunning"));
results.Add(error);
TaskService.Add(new SDTask(error));
@ -51,12 +51,12 @@ namespace ICSharpCode.SharpDevelop.Project @@ -51,12 +51,12 @@ namespace ICSharpCode.SharpDevelop.Project
}
} else {
guiBuildCancellation = new CancellationTokenSource();
IProgressMonitor progressMonitor = WorkbenchSingleton.StatusBar.CreateProgressMonitor(guiBuildCancellation.Token);
guiBuildTrackedFeature = AnalyticsMonitorService.TrackFeature("ICSharpCode.SharpDevelop.Project.BuildEngine.Build");
WorkbenchSingleton.StatusBar.SetMessage(StringParser.Parse("${res:MainWindow.CompilerMessages.BuildVerb}..."));
IProgressMonitor progressMonitor = SD.StatusBar.CreateProgressMonitor(guiBuildCancellation.Token);
guiBuildTrackedFeature = SD.AnalyticsMonitor.TrackFeature("ICSharpCode.SharpDevelop.Project.BuildEngine.Build");
SD.StatusBar.SetMessage(StringParser.Parse("${res:MainWindow.CompilerMessages.BuildVerb}..."));
ProjectService.RaiseEventBuildStarted(new BuildEventArgs(project, options));
StartBuild(project, options,
new MessageViewSink(TaskService.BuildMessageViewCategory, progressMonitor, WorkbenchSingleton.StatusBar));
new MessageViewSink(TaskService.BuildMessageViewCategory, progressMonitor, SD.StatusBar));
}
}

2
src/Main/Base/Project/Src/Project/Converter/UpgradeView.xaml.cs

@ -219,7 +219,7 @@ namespace ICSharpCode.SharpDevelop.Project.Converter @@ -219,7 +219,7 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
void convertButton_Click(object sender, RoutedEventArgs e)
{
Core.AnalyticsMonitorService.TrackFeature(GetType(), "convertButton_Click");
SD.AnalyticsMonitor.TrackFeature(GetType(), "convertButton_Click");
CompilerVersion selectedCompiler = newVersionComboBox.SelectedValue as CompilerVersion;
TargetFramework selectedFramework = newFrameworkComboBox.SelectedValue as TargetFramework;

2
src/Main/Base/Project/Src/Project/Converter/UpgradeViewContent.cs

@ -17,7 +17,7 @@ namespace ICSharpCode.SharpDevelop.Project.Converter @@ -17,7 +17,7 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
{
var projects = solution.Projects.OfType<IUpgradableProject>().ToList();
if (projects.Count > 0 && projects.All(u => u.UpgradeDesired)) {
Core.AnalyticsMonitorService.TrackFeature(typeof(UpgradeView), "opened automatically");
SD.AnalyticsMonitor.TrackFeature(typeof(UpgradeView), "opened automatically");
Show(solution).upgradeView.UpgradeViewOpenedAutomatically = true;
}
}

2
src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs

@ -113,7 +113,7 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -113,7 +113,7 @@ namespace ICSharpCode.SharpDevelop.Debugging
{
WorkbenchSingleton.Workbench.WorkbenchLayout.SwitchLayout("Debug");
debugFeature = AnalyticsMonitorService.TrackFeature("Debugger");
debugFeature = SD.AnalyticsMonitor.TrackFeature("Debugger");
ClearDebugMessages();

7
src/Main/Base/Project/Src/Services/SD.cs

@ -5,7 +5,6 @@ using System; @@ -5,7 +5,6 @@ using System;
using System.ComponentModel.Design;
using ICSharpCode.Core;
using ICSharpCode.Core.Implementation;
using ICSharpCode.Core.Services;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui;
@ -33,7 +32,7 @@ namespace ICSharpCode.SharpDevelop @@ -33,7 +32,7 @@ namespace ICSharpCode.SharpDevelop
/// </summary>
public static void InitializeForUnitTests()
{
var container = new ThreadSafeServiceContainer(ServiceSingleton.FallbackServiceProvider);
var container = new SharpDevelopServiceContainer(ServiceSingleton.FallbackServiceProvider);
PropertyService.InitializeServiceForUnitTests();
ServiceSingleton.ServiceProvider = container;
}
@ -79,5 +78,9 @@ namespace ICSharpCode.SharpDevelop @@ -79,5 +78,9 @@ namespace ICSharpCode.SharpDevelop
public static IEditorControlService EditorControlService {
get { return GetRequiredService<IEditorControlService>(); }
}
public static IAnalyticsMonitor AnalyticsMonitor {
get { return GetRequiredService<IAnalyticsMonitor>(); }
}
}
}

58
src/Main/Base/Project/Src/Util/ThreadSafeServiceContainer.cs → src/Main/Base/Project/Src/Util/SharpDevelopServiceContainer.cs

@ -11,62 +11,74 @@ namespace ICSharpCode.SharpDevelop @@ -11,62 +11,74 @@ namespace ICSharpCode.SharpDevelop
/// <summary>
/// A thread-safe service container class.
/// </summary>
public class ThreadSafeServiceContainer : IServiceProvider, IServiceContainer, IDisposable
public class SharpDevelopServiceContainer : IServiceProvider, IServiceContainer, IDisposable
{
readonly IServiceProvider parentProvider;
readonly Dictionary<Type, object> services = new Dictionary<Type, object>();
readonly List<IDisposable> servicesToDispose = new List<IDisposable>();
public ThreadSafeServiceContainer()
public SharpDevelopServiceContainer()
{
services.Add(typeof(ThreadSafeServiceContainer), this);
services.Add(typeof(SharpDevelopServiceContainer), this);
services.Add(typeof(IServiceContainer), this);
}
public ThreadSafeServiceContainer(IServiceProvider parentProvider) : this()
public SharpDevelopServiceContainer(IServiceProvider parentProvider) : this()
{
this.parentProvider = parentProvider;
}
public object GetService(Type serviceType)
{
bool foundService;
object instance;
lock (services) {
foundService = services.TryGetValue(serviceType, out instance);
}
if (!foundService)
return parentProvider != null ? parentProvider.GetService(serviceType) : null;
if (services.TryGetValue(serviceType, out instance)) {
ServiceCreatorCallback callback = instance as ServiceCreatorCallback;
if (callback == null)
return instance;
object newInstance = callback(this, serviceType);
lock (services) {
if (services.TryGetValue(serviceType, out instance) && ReferenceEquals(instance, callback)) {
services[serviceType] = newInstance;
return newInstance;
if (callback != null) {
SD.LoggingService.Debug("Service startup: " + serviceType);
instance = callback(this, serviceType);
if (instance != null) {
servicesToDispose.Add(instance as IDisposable);
services[serviceType] = instance;
} else {
services.Remove(serviceType);
}
}
}
// concurrent modification while running the callback (most likely another thread ran the callback first):
IDisposable disposable = newInstance as IDisposable;
if (disposable != null)
disposable.Dispose();
return GetService(serviceType); // retry
}
if (instance != null)
return instance;
else
return parentProvider != null ? parentProvider.GetService(serviceType) : null;
}
public void Dispose()
{
var loggingService = SD.LoggingService;
IDisposable[] disposables;
lock (services) {
disposables = services.Values.OfType<IDisposable>().ToArray();
disposables = servicesToDispose.ToArray();
services.Clear();
servicesToDispose.Clear();
}
foreach (IDisposable disposable in disposables)
// dispose services in reverse order of their creation
foreach (IDisposable disposable in disposables.Reverse()) {
if (disposable != null) {
loggingService.Debug("Service shutdown: " + disposable.GetType());
disposable.Dispose();
}
}
var eh = Disposed;
if (eh != null)
eh(this, EventArgs.Empty);
}
public event EventHandler Disposed;
public void AddService(Type serviceType, object serviceInstance)
{
lock (services) {
servicesToDispose.Add(serviceInstance as IDisposable);
services.Add(serviceType, serviceInstance);
}
}

4
src/Main/Core/Project/ICSharpCode.Core.csproj

@ -104,8 +104,7 @@ @@ -104,8 +104,7 @@
<Compile Include="Src\AddInTree\TreePathNotFoundException.cs" />
<Compile Include="Src\CoreException.cs" />
<Compile Include="Src\ExtensionMethods.cs" />
<Compile Include="Src\Services\AnalyticsMonitor\AnalyticsMonitorService.cs" />
<Compile Include="Src\Services\AnalyticsMonitor\IAnalyticsMonitor.cs" />
<Compile Include="Src\Services\AnalyticsMonitorService.cs" />
<Compile Include="Src\Services\ApplicationStateInfoService.cs" />
<Compile Include="Src\Services\FallbackServiceAttribute.cs" />
<Compile Include="Src\Services\FileUtility\FileName.cs" />
@ -147,7 +146,6 @@ @@ -147,7 +146,6 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Src\Services\LoggingService" />
<Folder Include="Src\Services\AnalyticsMonitor" />
<Folder Include="Src\Services\RegistryService" />
<Folder Include="Src\Services\ResourceService" />
<Content Include="..\..\..\..\data\schemas\AddIn.xsd">

6
src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs

@ -35,8 +35,12 @@ namespace ICSharpCode.Core @@ -35,8 +35,12 @@ namespace ICSharpCode.Core
public Type FindType(string className)
{
LoadDependencies();
foreach (Runtime runtime in runtimes) {
if (!runtime.IsHostApplicationAssembly) {
// Load dependencies only when a plugin library is first loaded.
// This allows looking in host assemblies for service IDs.
LoadDependencies();
}
Type t = runtime.FindType(className);
if (t != null) {
return t;

7
src/Main/Core/Project/Src/AddInTree/AddIn/Runtime.cs

@ -52,6 +52,13 @@ namespace ICSharpCode.Core @@ -52,6 +52,13 @@ namespace ICSharpCode.Core
get { return assembly; }
}
/// <summary>
/// Gets whether the assembly belongs to the host application (':' prefix).
/// </summary>
public bool IsHostApplicationAssembly {
get { return !string.IsNullOrEmpty(assembly) && assembly[0] == ':'; }
}
/// <summary>
/// Force loading the runtime assembly now.
/// </summary>

98
src/Main/Core/Project/Src/Services/AnalyticsMonitor/AnalyticsMonitorService.cs

@ -1,98 +0,0 @@ @@ -1,98 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.Core.Services;
using System;
namespace ICSharpCode.Core
{
/// <summary>
/// Allows marking the end-time of feature uses.
/// </summary>
/// <remarks>Implementations of this interface must be thread-safe.</remarks>
public interface IAnalyticsMonitorTrackedFeature
{
void EndTracking();
}
/// <summary>
/// Allows tracking feature use.
/// All methods on this class are thread-safe.
/// </summary>
public static class AnalyticsMonitorService
{
/// <summary>
/// Tracks an exception that has occurred.
/// </summary>
public static void TrackException(Exception exception)
{
if (exception == null)
throw new ArgumentNullException("exception");
IAnalyticsMonitor monitor = ServiceSingleton.ServiceProvider.GetService<IAnalyticsMonitor>();
if (monitor != null) {
monitor.TrackException(exception);
}
}
/// <summary>
/// Tracks a feature use.
/// </summary>
/// <param name="featureName">Name of the feature</param>
/// <returns>Object that can be used to 'end' the feature use, if measuring time spans is desired.</returns>
public static IAnalyticsMonitorTrackedFeature TrackFeature(string featureName)
{
return TrackFeature(featureName, null);
}
/// <summary>
/// Tracks a feature use.
/// </summary>
/// <param name="featureName">Name of the feature</param>
/// <param name="activationMethod">Method used to 'activate' the feature (e.g. Menu, Toolbar, Shortcut, etc.)</param>
/// <returns>Object that can be used to 'end' the feature use, if measuring time spans is desired.</returns>
public static IAnalyticsMonitorTrackedFeature TrackFeature(string featureName, string activationMethod)
{
if (featureName == null)
throw new ArgumentNullException("featureName");
if (activationMethod != null)
LoggingService.Debug("Activated feature '" + featureName + "', activation=" + activationMethod);
else
LoggingService.Debug("Activated feature '" + featureName + "'");
IAnalyticsMonitor monitor = ServiceSingleton.ServiceProvider.GetService<IAnalyticsMonitor>();
if (monitor != null) {
return monitor.TrackFeature(featureName, activationMethod) ?? DummyFeature.Instance;
} else {
return DummyFeature.Instance;
}
}
sealed class DummyFeature : IAnalyticsMonitorTrackedFeature
{
public static readonly DummyFeature Instance = new DummyFeature();
public void EndTracking()
{
}
}
/// <summary>
/// Tracks a feature use.
/// </summary>
/// <param name="featureClass">Class containing the feature</param>
/// <param name="featureName">Name of the feature</param>
/// <param name="activationMethod">Method used to 'activate' the feature (e.g. Menu, Toolbar, Shortcut, etc.)</param>
/// <returns>Object that can be used to 'end' the feature use, if measuring time spans is desired.</returns>
public static IAnalyticsMonitorTrackedFeature TrackFeature(Type featureClass, string featureName = null, string activationMethod = null)
{
if (featureClass == null)
throw new ArgumentNullException("featureClass");
if (featureName != null)
return TrackFeature(featureClass.FullName + "/" + featureName, activationMethod);
else
return TrackFeature(featureClass.FullName, activationMethod);
}
}
}

17
src/Main/Core/Project/Src/Services/AnalyticsMonitor/IAnalyticsMonitor.cs

@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
namespace ICSharpCode.Core.Services
{
/// <summary>
/// Interface for AnalyticsMonitorService.
/// </summary>
/// <remarks>Implementations of this interface must be thread-safe.</remarks>
public interface IAnalyticsMonitor
{
void TrackException(Exception exception);
IAnalyticsMonitorTrackedFeature TrackFeature(string featureName, string activationMethod);
}
}

67
src/Main/Core/Project/Src/Services/AnalyticsMonitorService.cs

@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
namespace ICSharpCode.Core
{
/// <summary>
/// Interface for AnalyticsMonitorService.
/// </summary>
/// <remarks>Implementations of this interface must be thread-safe.</remarks>
[FallbackService(typeof(AnalyticsMonitorFallback))]
public interface IAnalyticsMonitor
{
/// <summary>
/// Tracks an exception that has occurred.
/// </summary>
void TrackException(Exception exception);
/// <summary>
/// Tracks a feature use.
/// </summary>
/// <param name="featureName">Name of the feature</param>
/// <param name="activationMethod">Method used to 'activate' the feature (e.g. Menu, Toolbar, Shortcut, etc.)</param>
/// <returns>Object that can be used to 'end' the feature use, if measuring time spans is desired.</returns>
IAnalyticsMonitorTrackedFeature TrackFeature(string featureName, string activationMethod = null);
/// <summary>
/// Tracks a feature use.
/// </summary>
/// <param name="featureClass">Class containing the feature</param>
/// <param name="featureName">Name of the feature</param>
/// <param name="activationMethod">Method used to 'activate' the feature (e.g. Menu, Toolbar, Shortcut, etc.)</param>
/// <returns>Object that can be used to 'end' the feature use, if measuring time spans is desired.</returns>
IAnalyticsMonitorTrackedFeature TrackFeature(Type featureClass, string featureName = null, string activationMethod = null);
}
/// <summary>
/// Allows marking the end-time of feature uses.
/// </summary>
/// <remarks>Implementations of this interface must be thread-safe.</remarks>
public interface IAnalyticsMonitorTrackedFeature
{
void EndTracking();
}
sealed class AnalyticsMonitorFallback : IAnalyticsMonitor, IAnalyticsMonitorTrackedFeature
{
public void TrackException(Exception exception)
{
}
public IAnalyticsMonitorTrackedFeature TrackFeature(string featureName, string activationMethod)
{
return this;
}
public IAnalyticsMonitorTrackedFeature TrackFeature(Type featureClass, string featureName, string activationMethod)
{
return this;
}
void IAnalyticsMonitorTrackedFeature.EndTracking()
{
}
}
}

1
src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs

@ -8,7 +8,6 @@ using System.Linq; @@ -8,7 +8,6 @@ using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using ICSharpCode.Core.Services;
using Microsoft.Win32;
namespace ICSharpCode.Core

1
src/Main/Core/Project/Src/Services/LoggingService/LoggingService.cs

@ -2,7 +2,6 @@ @@ -2,7 +2,6 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using ICSharpCode.Core.Services;
namespace ICSharpCode.Core
{

1
src/Main/Core/Project/Src/Services/MessageService/MessageService.cs

@ -3,7 +3,6 @@ @@ -3,7 +3,6 @@
using System;
using System.Text;
using ICSharpCode.Core.Services;
namespace ICSharpCode.Core
{

1
src/Main/Core/Project/Src/Services/ServiceSingleton.cs

@ -6,7 +6,6 @@ using System.Collections.Generic; @@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.Design;
using ICSharpCode.Core.Implementation;
using ICSharpCode.Core.Services;
namespace ICSharpCode.Core
{

4
src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs

@ -181,7 +181,7 @@ namespace ICSharpCode.Core.Presentation @@ -181,7 +181,7 @@ namespace ICSharpCode.Core.Presentation
base.OnClick();
string feature = GetFeatureName();
if (!string.IsNullOrEmpty(feature)) {
AnalyticsMonitorService.TrackFeature(feature, ActivationMethod);
ServiceSingleton.ServiceProvider.GetRequiredService<IAnalyticsMonitor>().TrackFeature(feature, ActivationMethod);
}
}
@ -205,7 +205,7 @@ namespace ICSharpCode.Core.Presentation @@ -205,7 +205,7 @@ namespace ICSharpCode.Core.Presentation
public void Execute(object parameter)
{
AnalyticsMonitorService.TrackFeature(featureName, "Shortcut");
ServiceSingleton.ServiceProvider.GetRequiredService<IAnalyticsMonitor>().TrackFeature(featureName, "Shortcut");
baseCommand.Execute(parameter);
}

2
src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs

@ -59,7 +59,7 @@ namespace ICSharpCode.Core.Presentation @@ -59,7 +59,7 @@ namespace ICSharpCode.Core.Presentation
{
string feature = GetFeatureName();
if (!string.IsNullOrEmpty(feature)) {
AnalyticsMonitorService.TrackFeature(feature, "Toolbar");
ServiceSingleton.ServiceProvider.GetRequiredService<IAnalyticsMonitor>().TrackFeature(feature, "Toolbar");
}
base.OnClick();
}

2
src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs

@ -110,7 +110,7 @@ namespace ICSharpCode.Core.WinForms @@ -110,7 +110,7 @@ namespace ICSharpCode.Core.WinForms
if (GetVisible() && Enabled) {
ICommand cmd = Command;
if (cmd != null) {
AnalyticsMonitorService.TrackFeature(cmd.GetType().FullName, "Menu");
ServiceSingleton.ServiceProvider.GetRequiredService<IAnalyticsMonitor>().TrackFeature(cmd.GetType().FullName, "Menu");
cmd.Run();
}
}

2
src/Main/ICSharpCode.Core.WinForms/MessageService/IDialogMessageService.cs

@ -5,8 +5,6 @@ using System; @@ -5,8 +5,6 @@ using System;
using System.ComponentModel;
using System.Windows.Forms;
using ICSharpCode.Core.Services;
namespace ICSharpCode.Core.WinForms
{
/// <summary>

2
src/Main/ICSharpCode.Core.WinForms/MessageService/WinFormsMessageService.cs

@ -5,8 +5,6 @@ using System; @@ -5,8 +5,6 @@ using System;
using System.ComponentModel;
using System.Windows.Forms;
using ICSharpCode.Core.Services;
namespace ICSharpCode.Core.WinForms
{
/// <summary>

2
src/Main/ICSharpCode.Core.WinForms/ToolBar/ToolBarCommand.cs

@ -44,7 +44,7 @@ namespace ICSharpCode.Core.WinForms @@ -44,7 +44,7 @@ namespace ICSharpCode.Core.WinForms
}
if (menuCommand != null) {
menuCommand.Owner = caller;
AnalyticsMonitorService.TrackFeature(menuCommand.GetType().FullName, "Toolbar");
ServiceSingleton.ServiceProvider.GetRequiredService<IAnalyticsMonitor>().TrackFeature(menuCommand.GetType().FullName, "Toolbar");
menuCommand.Run();
}
}

2
src/Main/SharpDevelop/Gui/Workbench/AvalonDockLayout.cs

@ -191,7 +191,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Workbench @@ -191,7 +191,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Workbench
if (pads.TryGetValue(padDescriptor, out pad)) {
pad.Show(dockingManager);
} else {
LoggingService.Debug("Add pad " + padDescriptor.Class + " at " + padDescriptor.DefaultPosition);
//LoggingService.Debug("Add pad " + padDescriptor.Class + " at " + padDescriptor.DefaultPosition);
pad = new AvalonPadContent(this, padDescriptor);
pads.Add(padDescriptor, pad);

2
src/Main/SharpDevelop/Logging/ExceptionBox.cs

@ -84,7 +84,7 @@ namespace ICSharpCode.SharpDevelop.Logging @@ -84,7 +84,7 @@ namespace ICSharpCode.SharpDevelop.Logging
showingBox = true;
try {
try {
AnalyticsMonitorService.TrackException(exception);
SD.AnalyticsMonitor.TrackException(exception);
} catch (Exception ex) {
LoggingService.Warn("Error tracking exception", ex);
}

1
src/Main/SharpDevelop/Logging/SDMessageService.cs

@ -1,7 +1,6 @@ @@ -1,7 +1,6 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.Core.Services;
using System;
using ICSharpCode.Core.WinForms;

1
src/Main/SharpDevelop/Logging/log4netLoggingService.cs

@ -6,7 +6,6 @@ using System.Globalization; @@ -6,7 +6,6 @@ using System.Globalization;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.Core.Services;
using log4net;
using log4net.Config;

3
src/Main/SharpDevelop/Sda/CallHelper.cs

@ -38,7 +38,7 @@ namespace ICSharpCode.SharpDevelop.Sda @@ -38,7 +38,7 @@ namespace ICSharpCode.SharpDevelop.Sda
public void InitSharpDevelopCore(SharpDevelopHost.CallbackHelper callback, StartupSettings properties)
{
// Initialize the most important services:
var container = new ThreadSafeServiceContainer(ServiceSingleton.FallbackServiceProvider);
var container = new SharpDevelopServiceContainer(ServiceSingleton.FallbackServiceProvider);
container.AddService(typeof(IMessageService), new SDMessageService());
container.AddService(typeof(ILoggingService), new log4netLoggingService());
ServiceSingleton.ServiceProvider = container;
@ -180,6 +180,7 @@ namespace ICSharpCode.SharpDevelop.Sda @@ -180,6 +180,7 @@ namespace ICSharpCode.SharpDevelop.Sda
LoggingService.Info("Unloading services...");
try {
WorkbenchSingleton.OnWorkbenchUnloaded();
((IDisposable)SD.Services).Dispose(); // dispose all services
PropertyService.Save();
} catch (Exception ex) {
LoggingService.Warn("Exception during unloading", ex);

2
src/Main/SharpDevelop/app.template.config

@ -138,7 +138,7 @@ @@ -138,7 +138,7 @@
</appender>
<!--- Keeps the last few log entries and appends them to bug reports when an exception occurs -->
<appender name="Recorder" type="ICSharpCode.SharpDevelop.Sda.LogMessageRecorder, ICSharpCode.SharpDevelop.Sda">
<appender name="Recorder" type="ICSharpCode.SharpDevelop.Logging.LogMessageRecorder, SharpDevelop">
<bufferSize value="25" />
</appender>

Loading…
Cancel
Save