diff --git a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj
index 4bb8f7c783..c0e534e813 100644
--- a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj
+++ b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj
@@ -158,6 +158,7 @@
+
@@ -236,6 +237,7 @@
+
@@ -252,9 +254,11 @@
+
+
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/IPackageRepositoryFactoryEvents.cs b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageRepositoryFactoryEvents.cs
new file mode 100644
index 0000000000..e882a6f151
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageRepositoryFactoryEvents.cs
@@ -0,0 +1,12 @@
+// 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.PackageManagement
+{
+ public interface IPackageRepositoryFactoryEvents
+ {
+ event EventHandler RepositoryCreated;
+ }
+}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs
index 106bfc0b4e..5e9051d65e 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs
@@ -24,11 +24,13 @@ namespace ICSharpCode.PackageManagement
static readonly IPackageRepositoryCache projectTemplatePackageRepositoryCache;
static readonly RegisteredProjectTemplatePackageSources projectTemplatePackageSources;
static readonly PackageRepositoryCache packageRepositoryCache;
+ static readonly UserAgentGeneratorForRepositoryRequests userAgentGenerator;
static PackageManagementServices()
{
options = new PackageManagementOptions();
packageRepositoryCache = new PackageRepositoryCache(options.PackageSources, options.RecentPackages);
+ userAgentGenerator = new UserAgentGeneratorForRepositoryRequests(packageRepositoryCache);
registeredPackageRepositories = new RegisteredPackageRepositories(packageRepositoryCache, options);
projectTemplatePackageSources = new RegisteredProjectTemplatePackageSources();
projectTemplatePackageRepositoryCache = new ProjectTemplatePackageRepositoryCache(packageRepositoryCache, projectTemplatePackageSources);
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryCache.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryCache.cs
index aa05822a7e..c9d75ebc40 100644
--- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryCache.cs
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryCache.cs
@@ -8,7 +8,7 @@ using NuGet;
namespace ICSharpCode.PackageManagement
{
- public class PackageRepositoryCache : IPackageRepositoryCache
+ public class PackageRepositoryCache : IPackageRepositoryCache, IPackageRepositoryFactoryEvents
{
ISharpDevelopPackageRepositoryFactory factory;
RegisteredPackageSources registeredPackageSources;
@@ -37,6 +37,8 @@ namespace ICSharpCode.PackageManagement
{
}
+ public event EventHandler RepositoryCreated;
+
public IPackageRepository CreateRepository(string packageSource)
{
IPackageRepository repository = GetExistingRepository(packageSource);
@@ -59,9 +61,19 @@ namespace ICSharpCode.PackageManagement
{
IPackageRepository repository = factory.CreateRepository(packageSource);
repositories.TryAdd(packageSource, repository);
+
+ OnPackageRepositoryCreated(repository);
+
return repository;
}
+ void OnPackageRepositoryCreated(IPackageRepository repository)
+ {
+ if (RepositoryCreated != null) {
+ RepositoryCreated(this, new PackageRepositoryFactoryEventArgs(repository));
+ }
+ }
+
public ISharedPackageRepository CreateSharedRepository(IPackagePathResolver pathResolver, IFileSystem fileSystem, IFileSystem configSettingsFileSystem)
{
return factory.CreateSharedRepository(pathResolver, fileSystem, configSettingsFileSystem);
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryFactoryEventArgs.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryFactoryEventArgs.cs
new file mode 100644
index 0000000000..851c4b8d45
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryFactoryEventArgs.cs
@@ -0,0 +1,18 @@
+// 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;
+using NuGet;
+
+namespace ICSharpCode.PackageManagement
+{
+ public class PackageRepositoryFactoryEventArgs : EventArgs
+ {
+ public PackageRepositoryFactoryEventArgs(IPackageRepository repository)
+ {
+ this.Repository = repository;
+ }
+
+ public IPackageRepository Repository { get; private set; }
+ }
+}
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/SharpDevelopHttpUserAgent.cs b/src/AddIns/Misc/PackageManagement/Project/Src/SharpDevelopHttpUserAgent.cs
new file mode 100644
index 0000000000..885b9393fb
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/SharpDevelopHttpUserAgent.cs
@@ -0,0 +1,37 @@
+// 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;
+using NuGet;
+
+namespace ICSharpCode.PackageManagement
+{
+ public class SharpDevelopHttpUserAgent
+ {
+ public SharpDevelopHttpUserAgent()
+ {
+ CreateUserAgent();
+ }
+
+ public string Client { get; private set; }
+ public string Host { get; private set; }
+ public string UserAgent { get; private set; }
+
+ void CreateUserAgent()
+ {
+ Client = "SharpDevelop";
+ Host = GetHost();
+ UserAgent = HttpUtility.CreateUserAgentString(Client, Host);
+ }
+
+ string GetHost()
+ {
+ return String.Format("SharpDevelop/{0}", RevisionClass.FullVersion);
+ }
+
+ public override string ToString()
+ {
+ return UserAgent;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/UserAgentGeneratorForRepositoryRequests.cs b/src/AddIns/Misc/PackageManagement/Project/Src/UserAgentGeneratorForRepositoryRequests.cs
new file mode 100644
index 0000000000..72ce47e58c
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Project/Src/UserAgentGeneratorForRepositoryRequests.cs
@@ -0,0 +1,35 @@
+// 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;
+using NuGet;
+
+namespace ICSharpCode.PackageManagement
+{
+ public class UserAgentGeneratorForRepositoryRequests
+ {
+ SharpDevelopHttpUserAgent userAgent = new SharpDevelopHttpUserAgent();
+
+ public UserAgentGeneratorForRepositoryRequests(IPackageRepositoryFactoryEvents repositoryFactoryEvents)
+ {
+ repositoryFactoryEvents.RepositoryCreated += RepositoryCreated;
+ }
+
+ void RepositoryCreated(object sender, PackageRepositoryFactoryEventArgs e)
+ {
+ RegisterHttpClient(e.Repository as IHttpClientEvents);
+ }
+
+ void RegisterHttpClient(IHttpClientEvents clientEvents)
+ {
+ if (clientEvents != null) {
+ clientEvents.SendingRequest += SendingRequest;
+ }
+ }
+
+ void SendingRequest(object sender, WebRequestEventArgs e)
+ {
+ HttpUtility.SetUserAgent(e.Request, userAgent.ToString());
+ }
+ }
+}
diff --git a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj
index c4690abff0..66e56f446d 100644
--- a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj
+++ b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj
@@ -208,6 +208,7 @@
+
diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/PackageRepositoryCacheTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/PackageRepositoryCacheTests.cs
index 5bdbabacab..1c4ee897fb 100644
--- a/src/AddIns/Misc/PackageManagement/Test/Src/PackageRepositoryCacheTests.cs
+++ b/src/AddIns/Misc/PackageManagement/Test/Src/PackageRepositoryCacheTests.cs
@@ -355,5 +355,30 @@ namespace PackageManagement.Tests
Assert.IsNull(fakePackageRepositoryFactory.AggregateRepositoryPassedToCreateRecentPackageRepository);
}
+
+ [Test]
+ public void CreateRepository_NewRepositoryCreated_RepositoryCreatedEventFired()
+ {
+ CreateCache();
+ PackageRepositoryFactoryEventArgs eventArgs = null;
+ cache.RepositoryCreated += (sender, e) => eventArgs = e;
+
+ IPackageRepository repository = cache.CreateRepository(nuGetPackageSource.Source);
+
+ Assert.AreEqual(fakePackageRepositoryFactory.FakePackageRepository, eventArgs.Repository);
+ }
+
+ [Test]
+ public void CreateRepository_RepositoryCreatedTwice_RepositoryCreatedEventIsNotFiredOnSecondCallToCreateRepository()
+ {
+ CreateCache();
+ cache.CreateRepository(nuGetPackageSource.Source);
+ PackageRepositoryFactoryEventArgs eventArgs = null;
+ cache.RepositoryCreated += (sender, e) => eventArgs = e;
+
+ cache.CreateRepository(nuGetPackageSource.Source);
+
+ Assert.IsNull(eventArgs);
+ }
}
}
diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/UserAgentGeneratorForRepositoryRequestsTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/UserAgentGeneratorForRepositoryRequestsTests.cs
new file mode 100644
index 0000000000..1feb8c196a
--- /dev/null
+++ b/src/AddIns/Misc/PackageManagement/Test/Src/UserAgentGeneratorForRepositoryRequestsTests.cs
@@ -0,0 +1,90 @@
+// 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;
+using System.Net;
+using ICSharpCode.PackageManagement;
+using NuGet;
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace PackageManagement.Tests
+{
+ [TestFixture]
+ public class UserAgentGeneratorForRepositoryRequestsTests
+ {
+ UserAgentGeneratorForRepositoryRequests generator;
+ IPackageRepositoryFactoryEvents repositoryFactoryEvents;
+
+ void CreateGenerator()
+ {
+ repositoryFactoryEvents = MockRepository.GenerateStub();
+ generator = new UserAgentGeneratorForRepositoryRequests(repositoryFactoryEvents);
+ }
+
+ IPackageRepository CreatePackageRepository()
+ {
+ return MockRepository.GenerateStub();
+ }
+
+ IHttpClientEvents CreatePackageRepositoryThatImplementsIHttpClientEvents()
+ {
+ return MockRepository.GenerateMock();
+ }
+
+ void FireRepositoryCreatedEvent(IHttpClientEvents clientEvents)
+ {
+ FireRepositoryCreatedEvent(clientEvents as IPackageRepository);
+ }
+
+ void FireRepositoryCreatedEvent(IPackageRepository repository)
+ {
+ var eventArgs = new PackageRepositoryFactoryEventArgs(repository);
+ repositoryFactoryEvents.Raise(
+ events => events.RepositoryCreated += null,
+ repositoryFactoryEvents,
+ eventArgs);
+ }
+
+ WebRequest FireSendingRequestEvent(IHttpClientEvents clientEvents)
+ {
+ WebRequest request = CreateWebRequest();
+ request.Headers = new WebHeaderCollection();
+
+ var eventArgs = new WebRequestEventArgs(request);
+ clientEvents.Raise(
+ events => events.SendingRequest += null,
+ clientEvents,
+ eventArgs);
+
+ return request;
+ }
+
+ WebRequest CreateWebRequest()
+ {
+ return MockRepository.GenerateStub();
+ }
+
+ [Test]
+ public void SendingRequest_UserAgentGeneration_UserAgentSetOnRequest()
+ {
+ CreateGenerator();
+ IHttpClientEvents clientEvents = CreatePackageRepositoryThatImplementsIHttpClientEvents();
+ FireRepositoryCreatedEvent(clientEvents);
+
+ WebRequest request = FireSendingRequestEvent(clientEvents);
+
+ string userAgent = request.Headers[HttpRequestHeader.UserAgent];
+ Assert.IsTrue(userAgent.StartsWith("SharpDevelop"), userAgent);
+ }
+
+ [Test]
+ public void RepositoryCreated_RepositoryDoesNotImplementIHttpClientEvents_NullReferenceExceptionNotThrown()
+ {
+ CreateGenerator();
+ IPackageRepository repository = CreatePackageRepository();
+
+ FireRepositoryCreatedEvent(repository);
+ }
+ }
+}