Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
b64c34f8bd
40
EPS.SDK/Caching/Cache.cs
Normal file
40
EPS.SDK/Caching/Cache.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using ExtensiblePortfolioSite.SDK.Resources;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ExtensiblePortfolioSite.SDK.Caching
|
||||
{
|
||||
/// <summary>
|
||||
/// Global Item Cache
|
||||
/// </summary>
|
||||
public static class Cache
|
||||
{
|
||||
internal static TimeSpan GitUserLifetime = TimeSpan.FromMinutes(1440);
|
||||
internal static TimeSpan GitRepositoryLifetime = TimeSpan.FromMinutes(120);
|
||||
|
||||
private static readonly SortedDictionary<String, GitServiceCache> CacheLookup = new();
|
||||
|
||||
/// <summary>
|
||||
/// Retrives the specified <see cref="GitServiceCache"/> for the given provider
|
||||
/// </summary>
|
||||
/// <param name="ServiceProvider">Git Service Provider Name</param>
|
||||
/// <returns>Git Service Cache</returns>
|
||||
public static GitServiceCache GetGitServiceCache(String ServiceProvider)
|
||||
{
|
||||
if (CacheLookup.TryGetValue(ServiceProvider, out GitServiceCache? cache))
|
||||
return cache;
|
||||
lock (CacheLookup)
|
||||
{
|
||||
if (CacheLookup.TryGetValue(ServiceProvider, out cache))
|
||||
return cache;
|
||||
|
||||
ServiceProvider = string.Intern(ServiceProvider);
|
||||
|
||||
cache = new GitServiceCache(ServiceProvider);
|
||||
CacheLookup.Add(ServiceProvider, cache);
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
EPS.SDK/Caching/CacheRepo.cs
Normal file
16
EPS.SDK/Caching/CacheRepo.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using ExtensiblePortfolioSite.SDK.Git;
|
||||
|
||||
using System;
|
||||
|
||||
namespace ExtensiblePortfolioSite.SDK.Caching
|
||||
{
|
||||
internal sealed class CacheRepo : GitCacheItemBase<IRepository>
|
||||
{
|
||||
private readonly Uri Repository;
|
||||
|
||||
internal CacheRepo(GitServiceCache Parent, Uri Repository) : base(Parent) => this.Repository = Repository;
|
||||
|
||||
protected override TimeSpan Lifetime => Cache.GitRepositoryLifetime;
|
||||
protected override IRepository RetriveValue() => this.Parent.ServiceProvider.GetRepository(this.Repository);
|
||||
}
|
||||
}
|
||||
16
EPS.SDK/Caching/CacheUser.cs
Normal file
16
EPS.SDK/Caching/CacheUser.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using ExtensiblePortfolioSite.SDK.Git;
|
||||
|
||||
using System;
|
||||
|
||||
namespace ExtensiblePortfolioSite.SDK.Caching
|
||||
{
|
||||
internal sealed class CacheUser : GitCacheItemBase<IUser>
|
||||
{
|
||||
private readonly Uri User;
|
||||
|
||||
internal CacheUser(GitServiceCache Parent, Uri User) : base(Parent) => this.User = User;
|
||||
|
||||
protected override TimeSpan Lifetime => Cache.GitRepositoryLifetime;
|
||||
protected override IUser RetriveValue() => this.Parent.ServiceProvider.GetUser(this.User);
|
||||
}
|
||||
}
|
||||
80
EPS.SDK/Caching/GitCacheItemBase.cs
Normal file
80
EPS.SDK/Caching/GitCacheItemBase.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using System;
|
||||
|
||||
namespace ExtensiblePortfolioSite.SDK.Caching
|
||||
{
|
||||
/// <summary>
|
||||
/// Base Git Cache Item Class
|
||||
/// </summary>
|
||||
public abstract class GitCacheItemBase : IDisposable, ICacheItem
|
||||
{
|
||||
/// <summary>
|
||||
/// the <see cref="GitServiceCache"/> this Item is bound to
|
||||
/// </summary>
|
||||
protected readonly GitServiceCache Parent;
|
||||
|
||||
/// <inheritdoc cref="GitCacheItemBase"/>
|
||||
/// <param name="Parent"><see cref="GitServiceCache"/> that this Item is boud to</param>
|
||||
public GitCacheItemBase(GitServiceCache Parent)
|
||||
{
|
||||
this.Parent = Parent;
|
||||
Parent.Register(this);
|
||||
}
|
||||
///
|
||||
~GitCacheItemBase() => this.Disposing();
|
||||
|
||||
/// <inheritdoc cref="ICacheItem.Invalidate"/>
|
||||
public abstract void Invalidate();
|
||||
|
||||
/// <inheritdoc cref="IDisposable.Dispose"/>
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
this.Disposing();
|
||||
}
|
||||
private void Disposing() => this.Parent.Unregister(this);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base Git Cache Item Class
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Cache </typeparam>
|
||||
public abstract class GitCacheItemBase<T> : GitCacheItemBase, ICacheItem<T>
|
||||
{
|
||||
private T CacheValue;
|
||||
private DateTime RetrivedTime;
|
||||
|
||||
internal GitCacheItemBase(GitServiceCache Parent) : base(Parent)
|
||||
{
|
||||
this.RetrivedTime = DateTime.MinValue;
|
||||
this.CacheValue = default!;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="GitCacheItemBase.Invalidate"/>
|
||||
public override void Invalidate()
|
||||
{
|
||||
this.CacheValue = default!;
|
||||
this.RetrivedTime = DateTime.MinValue;
|
||||
}
|
||||
/// <inheritdoc cref="ICacheItem{T}.GetValue"/>
|
||||
public T GetValue()
|
||||
{
|
||||
if (DateTime.Now - this.RetrivedTime > this.Lifetime)
|
||||
{
|
||||
this.CacheValue = RetriveValue();
|
||||
this.RetrivedTime = DateTime.Now;
|
||||
}
|
||||
return this.CacheValue!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Expected Cache Item Lifetime
|
||||
/// </summary>
|
||||
protected abstract TimeSpan Lifetime { get; }
|
||||
/// <summary>
|
||||
/// Retrive the Cache Item
|
||||
/// </summary>
|
||||
/// <returns>Cache Item</returns>
|
||||
protected abstract T RetriveValue();
|
||||
}
|
||||
}
|
||||
107
EPS.SDK/Caching/GitServiceCache.cs
Normal file
107
EPS.SDK/Caching/GitServiceCache.cs
Normal file
@ -0,0 +1,107 @@
|
||||
using ExtensiblePortfolioSite.SDK.Git;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ExtensiblePortfolioSite.SDK.Caching
|
||||
{
|
||||
/// <summary>
|
||||
/// Git Service Cache Provider
|
||||
/// </summary>
|
||||
public sealed class GitServiceCache : IGitCacheProvider, IDisposable
|
||||
{
|
||||
/// <inheritdoc cref="IGitCacheProvider.ServiceProvider"/>
|
||||
public GitService ServiceProvider { get; }
|
||||
private readonly LinkedList<GitCacheItemBase> CacheItems = new();
|
||||
private Boolean _disposing = false;
|
||||
|
||||
internal GitServiceCache(String Provider) : this(GitManager.GetService(Provider)) { }
|
||||
internal GitServiceCache(GitService ServiceProvider)
|
||||
{
|
||||
this.ServiceProvider = ServiceProvider;
|
||||
this.ServiceProvider.OnChange += ServiceProvider_OnChange;
|
||||
}
|
||||
|
||||
private void ServiceProvider_OnChange(GitService Git)
|
||||
{
|
||||
lock(this.CacheItems)
|
||||
{
|
||||
foreach (GitCacheItemBase Item in this.CacheItems)
|
||||
Item.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private readonly SortedDictionary<String, GitCacheItemBase<IUser>> UserCaches = new();
|
||||
private readonly SortedDictionary<String, GitCacheItemBase<IRepository>> RepositoryCaches = new();
|
||||
|
||||
|
||||
/// <inheritdoc cref="IGitCacheProvider.GetUser(Uri)"/>
|
||||
public GitCacheItemBase<IUser> GetUser(Uri UserProfile)
|
||||
{
|
||||
String url = UserProfile.ToString();
|
||||
if (UserCaches.TryGetValue(url, out GitCacheItemBase<IUser>? cache))
|
||||
return cache;
|
||||
|
||||
lock (UserCaches)
|
||||
{
|
||||
if (UserCaches.TryGetValue(url, out cache))
|
||||
return cache;
|
||||
|
||||
cache = new CacheUser(this, UserProfile);
|
||||
UserCaches.Add(url, cache);
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
/// <inheritdoc cref="IGitCacheProvider.GetRepository(Uri)"/>
|
||||
public GitCacheItemBase<IRepository> GetRepository(Uri RepositoryURL)
|
||||
{
|
||||
String url = RepositoryURL.ToString();
|
||||
if (RepositoryCaches.TryGetValue(url, out GitCacheItemBase<IRepository>? cache))
|
||||
return cache;
|
||||
|
||||
lock (RepositoryCaches)
|
||||
{
|
||||
if (RepositoryCaches.TryGetValue(url, out cache))
|
||||
return cache;
|
||||
|
||||
cache = new CacheRepo(this, RepositoryURL);
|
||||
RepositoryCaches.Add(url, cache);
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc cref="ICacheProvider{GitCacheItemBase}.Register(GitCacheItemBase)"/>
|
||||
public void Register(GitCacheItemBase CacheItem)
|
||||
{
|
||||
if (!_disposing)
|
||||
lock (CacheItems)
|
||||
{
|
||||
this.CacheItems.AddFirst(CacheItem);
|
||||
}
|
||||
}
|
||||
/// <inheritdoc cref="ICacheProvider{GitCacheItemBase}.Unregister(GitCacheItemBase)"/>
|
||||
public void Unregister(GitCacheItemBase CacheItem)
|
||||
{
|
||||
if (!_disposing)
|
||||
lock (CacheItems)
|
||||
if (this.CacheItems.Remove(CacheItem)) ;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc cref="IDisposable"/>
|
||||
public void Dispose()
|
||||
{
|
||||
_disposing = true;
|
||||
lock (CacheItems)
|
||||
{
|
||||
this.ServiceProvider.OnChange -= ServiceProvider_OnChange;
|
||||
this.RepositoryCaches.Clear();
|
||||
this.UserCaches.Clear();
|
||||
foreach (GitCacheItemBase Item in CacheItems)
|
||||
Item.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
79
EPS.SDK/Caching/interfaces.cs
Normal file
79
EPS.SDK/Caching/interfaces.cs
Normal file
@ -0,0 +1,79 @@
|
||||
using ExtensiblePortfolioSite.SDK.Git;
|
||||
|
||||
using System;
|
||||
|
||||
namespace ExtensiblePortfolioSite.SDK.Caching
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Cache Item Provider
|
||||
/// </summary>
|
||||
/// <typeparam name="TCacheItemType">Cache Item Base Type</typeparam>
|
||||
public interface ICacheProvider<TCacheItemType> where TCacheItemType : ICacheItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers a Cache Item
|
||||
/// </summary>
|
||||
/// <param name="Item"></param>
|
||||
void Register(TCacheItemType Item);
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters a Cache Item
|
||||
/// </summary>
|
||||
/// <param name="Item"></param>
|
||||
void Unregister(TCacheItemType Item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Cache Item
|
||||
/// </summary>
|
||||
public interface ICacheItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Invalidates the Cache Item
|
||||
/// </summary>
|
||||
void Invalidate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Cache Item of Type <typeparamref name="T"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Cache Item Type</typeparam>
|
||||
public interface ICacheItem<T> : ICacheItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the Requested Cache Item
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
T GetValue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Git Cache Invalidate or Changed Delegate Callback
|
||||
/// </summary>
|
||||
public delegate void GitCacheInvalidateDelegate();
|
||||
|
||||
/// <summary>
|
||||
/// A Git Cache Provider
|
||||
/// </summary>
|
||||
public interface IGitCacheProvider : ICacheProvider<GitCacheItemBase>
|
||||
{
|
||||
/// <summary>
|
||||
/// The Service Provider tied to this Cache
|
||||
/// </summary>
|
||||
public GitService ServiceProvider { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get a User by its URL
|
||||
/// </summary>
|
||||
/// <param name="UserProfile">User Profile URL</param>
|
||||
/// <returns></returns>
|
||||
public GitCacheItemBase<IUser> GetUser(Uri UserProfile);
|
||||
/// <summary>
|
||||
/// Get a Repositroy by its URL
|
||||
/// </summary>
|
||||
/// <param name="RepositoryURL">Repository URL</param>
|
||||
/// <returns></returns>
|
||||
public GitCacheItemBase<IRepository> GetRepository(Uri RepositoryURL);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using ExtensiblePortfolioSite.SDK.Plugins;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ExtensiblePortfolioSite.SDK.Git
|
||||
@ -7,34 +9,6 @@ namespace ExtensiblePortfolioSite.SDK.Git
|
||||
{
|
||||
private static readonly SortedDictionary<String, GitService> Providers = new();
|
||||
|
||||
public static void Register(String Service, IGitProvider Provider)
|
||||
{
|
||||
Console.WriteLine($"Registering service {Service}");
|
||||
if (Providers.TryGetValue(Service, out GitService? GitService))
|
||||
{
|
||||
GitService.addProvider(Provider);
|
||||
return;
|
||||
}
|
||||
lock (Providers)
|
||||
{
|
||||
if (Providers.TryGetValue(Service, out GitService))
|
||||
{
|
||||
GitService.addProvider(Provider);
|
||||
return;
|
||||
}
|
||||
|
||||
GitService = new GitService(Service);
|
||||
GitService.addProvider(Provider);
|
||||
Providers.Add(Service, GitService);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Unregister(String Service, IGitProvider Provider)
|
||||
{
|
||||
if (Providers.TryGetValue(Service, out GitService? GitService))
|
||||
GitService.removeProvider(Provider);
|
||||
}
|
||||
|
||||
public static GitService GetService(String Website) => Providers[Website];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,54 +1,99 @@
|
||||
using System;
|
||||
using ExtensiblePortfolioSite.SDK.Caching;
|
||||
using ExtensiblePortfolioSite.SDK.Plugins;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ExtensiblePortfolioSite.SDK.Git
|
||||
{
|
||||
internal class GitService
|
||||
/// <summary>
|
||||
/// Git Service Changed Delegate/Callback
|
||||
/// </summary>
|
||||
/// <param name="Git">Sender</param>
|
||||
public delegate void GitServiceChangedDelegate(GitService Git);
|
||||
|
||||
/// <summary>
|
||||
/// Git Service
|
||||
/// </summary>
|
||||
public sealed class GitService
|
||||
{
|
||||
/// <summary>
|
||||
/// Git Service Name
|
||||
/// </summary>
|
||||
public String Service { get; }
|
||||
|
||||
public GitService(String Service)
|
||||
/// <summary>
|
||||
/// OnChanged Event Callback
|
||||
/// </summary>
|
||||
public event GitServiceChangedDelegate? OnChange;
|
||||
|
||||
internal GitService(String Service) => this.Service = Service;
|
||||
|
||||
private readonly SortedDictionary<String, IGitProvider> Providers = new();
|
||||
|
||||
internal void I_RemoveProvider(Plugin FromPlugin, IGitProvider provider)
|
||||
{
|
||||
this.Service = Service;
|
||||
lock (this.Providers)
|
||||
this.Providers.Add(FromPlugin.Info.Name, provider);
|
||||
|
||||
OnChange?.Invoke(this);
|
||||
}
|
||||
internal void I_AddProvider(Plugin FromPlugin, IGitProvider provider)
|
||||
{
|
||||
lock (this.Providers)
|
||||
this.Providers.Add(FromPlugin.Info.Name, provider);
|
||||
|
||||
OnChange?.Invoke(this);
|
||||
}
|
||||
|
||||
private readonly List<IGitProvider> Providers = new();
|
||||
private GitServiceCache? ServiceCache;
|
||||
|
||||
internal void removeProvider(IGitProvider provider)
|
||||
/// <summary>
|
||||
/// Gets the Service Cache
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public GitServiceCache GetCache() => this.ServiceCache ??= Cache.GetGitServiceCache(this.Service);
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to Retrive a GitProvider by its PluginName
|
||||
/// </summary>
|
||||
/// <param name="PluginName"></param>
|
||||
/// <param name="Provider"></param>
|
||||
/// <returns></returns>
|
||||
public void TryGetProviderByPlugin(String PluginName, out IGitProvider? Provider) => this.Providers.TryGetValue(PluginName, out Provider);
|
||||
|
||||
/// <summary>
|
||||
/// Retrives a Specified User by URL
|
||||
/// </summary>
|
||||
/// <param name="URL"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="GitObjectNotFoundException"></exception>
|
||||
public IUser GetUser(Uri URL)
|
||||
{
|
||||
lock (this.Providers)
|
||||
this.Providers.Remove(provider);
|
||||
}
|
||||
internal void addProvider(IGitProvider provider)
|
||||
{
|
||||
lock (this.Providers)
|
||||
this.Providers.Add(provider);
|
||||
}
|
||||
|
||||
public IUser GetUser(Uri Path)
|
||||
{
|
||||
lock (this.Providers)
|
||||
{
|
||||
foreach(IGitProvider Provider in this.Providers)
|
||||
if (Provider.TryGetUserByURL(Path, out IUser? User))
|
||||
foreach (IGitProvider Provider in this.Providers.Values)
|
||||
if (Provider.TryGetUserByURL(URL, out IUser? User))
|
||||
return User!;
|
||||
|
||||
throw new GitObjectNotFoundException(GitReferenceKind.User, Path);
|
||||
}
|
||||
|
||||
throw new GitObjectNotFoundException(GitReferenceKind.User, URL);
|
||||
|
||||
}
|
||||
public IRepository GetRepository(Uri Path)
|
||||
|
||||
/// <summary>
|
||||
/// Retrives a Specified Repository by URL
|
||||
/// </summary>
|
||||
/// <param name="URL"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="GitObjectNotFoundException"></exception>
|
||||
public IRepository GetRepository(Uri URL)
|
||||
{
|
||||
lock (this.Providers)
|
||||
{
|
||||
foreach (IGitProvider Provider in this.Providers)
|
||||
if (Provider.TryGetRepositoryByURL(Path, out IRepository? Repository))
|
||||
foreach (IGitProvider Provider in this.Providers.Values)
|
||||
if (Provider.TryGetRepositoryByURL(URL, out IRepository? Repository))
|
||||
return Repository!;
|
||||
|
||||
throw new GitObjectNotFoundException(GitReferenceKind.User, Path);
|
||||
}
|
||||
throw new GitObjectNotFoundException(GitReferenceKind.Repository, URL);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ExtensiblePortfolioSite.SDK.Git
|
||||
{
|
||||
@ -30,19 +26,19 @@ namespace ExtensiblePortfolioSite.SDK.Git
|
||||
/// <summary>
|
||||
/// Attempts to Get a User Profile by its Website URL
|
||||
/// </summary>
|
||||
public Boolean TryGetRepositoryByURL(Uri UserProfile, out IRepository? Repository);
|
||||
public Boolean TryGetRepositoryByURL(Uri URL, out IRepository? Repository);
|
||||
|
||||
/// <summary>
|
||||
/// Get a User Profile by its Website URL
|
||||
/// </summary>
|
||||
public IUser GetUserByURL(Uri UserProfile) =>
|
||||
TryGetUserByURL(UserProfile, out IUser? user)
|
||||
public IUser GetUserByURL(Uri URL) =>
|
||||
TryGetUserByURL(URL, out IUser? user)
|
||||
? user!
|
||||
: throw new GitObjectNotFoundException(GitReferenceKind.User, UserProfile);
|
||||
: throw new GitObjectNotFoundException(GitReferenceKind.User, URL);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to Get a User Profile by its Website URL
|
||||
/// </summary>
|
||||
public Boolean TryGetUserByURL(Uri UserProfile, out IUser? User);
|
||||
public Boolean TryGetUserByURL(Uri URL, out IUser? User);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
|
||||
@ -9,6 +9,7 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace ExtensiblePortfolioSite.SDK.Plugins
|
||||
{
|
||||
internal delegate void PluginUnloadDelegate(Plugin plugin);
|
||||
internal class Plugin : IPluginManagedLibrary
|
||||
{
|
||||
private class PluginLoadContext : AssemblyLoadContext
|
||||
@ -42,6 +43,8 @@ namespace ExtensiblePortfolioSite.SDK.Plugins
|
||||
public Assembly Assembly { get; private set; }
|
||||
public EPSPluginAttribute Info { get; private set; }
|
||||
|
||||
public event PluginUnloadDelegate? OnUnloading;
|
||||
|
||||
public IList<IPluginLibrary> Dependents { get; } = new List<IPluginLibrary>();
|
||||
IReadOnlyList<IPluginLibrary> IPluginLibrary.References => References.AsReadOnly();
|
||||
public List<IPluginLibrary> References = new();
|
||||
@ -58,8 +61,8 @@ namespace ExtensiblePortfolioSite.SDK.Plugins
|
||||
}
|
||||
|
||||
private readonly List<JsonConverter> JsonConverters = new();
|
||||
private readonly List<KeyValuePair<Type, String[]>> ResourceContainers = new();
|
||||
private readonly List<KeyValuePair<String, IGitProvider>> GitProviders = new();
|
||||
private readonly Dictionary<Type, String[]> ResourceContainers = new();
|
||||
private readonly Dictionary<GitService, IGitProvider> GitProviders = new();
|
||||
public void Init()
|
||||
{
|
||||
if (Initialized)
|
||||
@ -76,8 +79,9 @@ namespace ExtensiblePortfolioSite.SDK.Plugins
|
||||
if (t.IsAssignableTo(typeof(IGitProvider)) && t.GetConstructor(Type.EmptyTypes) != null)
|
||||
if (Activator.CreateInstance(t, true) is IGitProvider Provider)
|
||||
{
|
||||
GitManager.Register(GitProviderAttr.ServiceName, Provider);
|
||||
GitProviders.Add(new(GitProviderAttr.ServiceName, Provider));
|
||||
GitService Service = GitManager.GetService(GitProviderAttr.ServiceName);
|
||||
GitProviders.Add(Service, Provider);
|
||||
Service.I_AddProvider(this, Provider);
|
||||
}
|
||||
else
|
||||
PluginManager.LogMessage(PluginErrorSeverity.Error, this, "Failed to Instantiate GitProvider", t, null);
|
||||
@ -105,13 +109,14 @@ namespace ExtensiblePortfolioSite.SDK.Plugins
|
||||
{
|
||||
try
|
||||
{
|
||||
ResourceContainers.Add(t, ResourceContainerAttr.Schemes);
|
||||
ResourceManager.Register(t, ResourceContainerAttr.Schemes);
|
||||
ResourceContainers.Add(new(t, ResourceContainerAttr.Schemes));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PluginManager.LogMessage(PluginErrorSeverity.Fatal, this, "Faield to Create ResoruceContainer Factory", t, ex);
|
||||
throw new Exception("Runtime Unstable!", ex);
|
||||
PluginManager.LogMessage(PluginErrorSeverity.Fatal, this, "Failed to Create ResoruceContainer Factory", t, ex);
|
||||
Console.Error.WriteLine("Runtime Unstable, Exitting!");
|
||||
Environment.Exit(5);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -122,8 +127,10 @@ namespace ExtensiblePortfolioSite.SDK.Plugins
|
||||
|
||||
public void Disposing()
|
||||
{
|
||||
foreach (KeyValuePair<String, IGitProvider> provider in GitProviders)
|
||||
GitManager.Unregister(provider.Key, provider.Value);
|
||||
OnUnloading?.Invoke(this);
|
||||
|
||||
foreach (KeyValuePair<GitService, IGitProvider> provider in GitProviders)
|
||||
provider.Key.I_RemoveProvider(this, provider.Value);
|
||||
this.GitProviders.Clear();
|
||||
|
||||
foreach (KeyValuePair<Type, String[]> resourceContainer in ResourceContainers)
|
||||
|
||||
@ -55,9 +55,7 @@ namespace ExtensiblePortfolioSite.SDK.Plugins
|
||||
Directory.CreateDirectory(RootPath);
|
||||
LibraryPaths.Add(RootPath);
|
||||
foreach (String Dll in Directory.EnumerateFiles(RootPath, "*.dll", SearchOption.TopDirectoryOnly))
|
||||
{
|
||||
TryLoadPlugin(Path.GetFullPath(Dll, RootPath), out Plugin? _);
|
||||
}
|
||||
}
|
||||
public static Boolean TryLoadPlugin(string AsmPath, out Plugin? plugin)
|
||||
{
|
||||
@ -380,5 +378,15 @@ namespace ExtensiblePortfolioSite.SDK.Plugins
|
||||
// we want to throw when its trying to load something we don't explicitly allow!
|
||||
throw new FileNotFoundException($"Unable to Load Assembly '{Name}'");
|
||||
}
|
||||
|
||||
internal static Plugin? ResolveTypeToPlugin(Type type)
|
||||
{
|
||||
String fname = type.Assembly.GetName().FullName;
|
||||
lock (_plugins)
|
||||
foreach (Plugin plugin in _plugins)
|
||||
if (plugin.Assembly.GetName().FullName == fname)
|
||||
return plugin;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
using ExtensiblePortfolioSite.SDK;
|
||||
using ExtensiblePortfolioSite.SDK.Caching;
|
||||
using ExtensiblePortfolioSite.SDK.Git;
|
||||
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ExtensiblePortfolioSite
|
||||
@ -111,6 +112,8 @@ namespace ExtensiblePortfolioSite
|
||||
if (Repository == null) throw new Exception("GitRepo Repository missing!");
|
||||
if (Description == null) throw new Exception("GitRepo Description missing!");
|
||||
}
|
||||
|
||||
public IRepository Resolve() => GitManager.GetService(this.ServiceProvider).GetRepository(this.Repository);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@ -138,10 +141,6 @@ namespace ExtensiblePortfolioSite
|
||||
[Serializable]
|
||||
public class Cache
|
||||
{
|
||||
[JsonPropertyName("GitCommit")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public Int32 GitCommit = 30;
|
||||
|
||||
[JsonPropertyName("GitRepo")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public Int32 GitRepo = 120;
|
||||
@ -196,6 +195,10 @@ namespace ExtensiblePortfolioSite
|
||||
Conf = Json.Deserialize<ConfigObject>(File.ReadAllText(ConfigFile));
|
||||
if (Conf == null)
|
||||
throw new Exception("Failed to Load Config!");
|
||||
|
||||
// Load Config
|
||||
Cache.GitUserLifetime = TimeSpan.FromMinutes(Conf.CacheSection.GitUser);
|
||||
Cache.GitRepositoryLifetime = TimeSpan.FromMinutes(Conf.CacheSection.GitRepo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,8 +27,12 @@
|
||||
<None Include="Pages\Projects\Index.cshtml" />
|
||||
</ItemGroup>
|
||||
|
||||
<Folder Include="logs\" />
|
||||
<Folder Include="Plugins\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Target Name="IncludePlugins" BeforeTargets="AfterBuild">
|
||||
<MSBuild Projects="..\GithubPlugin\GithubPlugin.csproj" BuildInParallel="$(BuildInParallel)" Targets="Build">
|
||||
<MSBuild Projects="..\GithubPlugin\GithubPlugin.csproj" BuildInParallel="$(BuildInParallel)" Targets="Rebuild">
|
||||
</MSBuild>
|
||||
<Copy SourceFiles="$(SolutionDir)GithubPlugin\bin\$(Configuration)\net6.0\GithubPlugin.dll" DestinationFolder="Plugins/" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
|
||||
@ -25,14 +25,14 @@ namespace ExtensiblePortfolioSite
|
||||
{
|
||||
this.Parent = Parent;
|
||||
this.Identifier = Identifier;
|
||||
this.Parent.ScopeStack.AddLast(this);
|
||||
lock (this.Parent.ScopeStack)
|
||||
this.Parent.ScopeStack.AddLast(this);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// we shouldn't need this but we evidently do...
|
||||
// some form of race condition is causing a null ref Exception
|
||||
try { this.Parent.ScopeStack.Remove(this); } catch { }
|
||||
lock (this.Parent.ScopeStack)
|
||||
this.Parent.ScopeStack.Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace ExtensiblePortfolioSite.Pages.About
|
||||
{
|
||||
[ResponseCache(Duration = 60, Location = ResponseCacheLocation.Any, NoStore = false)]
|
||||
public class AboutModel : PageModel
|
||||
{
|
||||
public void OnGet()
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace ExtensiblePortfolioSite.Pages
|
||||
{
|
||||
[ResponseCache(Duration = 60, Location = ResponseCacheLocation.Any, NoStore = false)]
|
||||
public class IndexModel : PageModel
|
||||
{
|
||||
private readonly ILogger<IndexModel> _logger;
|
||||
@ -13,7 +15,7 @@ namespace ExtensiblePortfolioSite.Pages
|
||||
|
||||
public void OnGet()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,9 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace ExtensiblePortfolioSite.Pages
|
||||
{
|
||||
[ResponseCache(Duration = 60, Location = ResponseCacheLocation.Any, NoStore = false)]
|
||||
public class ProjectsModel : PageModel
|
||||
{
|
||||
private readonly ILogger<IndexModel> _logger;
|
||||
|
||||
@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace ExtensiblePortfolioSite.Pages.Socials
|
||||
{
|
||||
[ResponseCache(Duration = 60, Location = ResponseCacheLocation.Any, NoStore = false)]
|
||||
public class SocialsModel : PageModel
|
||||
{
|
||||
public void OnGet()
|
||||
|
||||
@ -93,12 +93,14 @@ namespace ExtensiblePortfolioSite
|
||||
// TODO: [Plugin] Web Static Files Provider
|
||||
// TODO: [Plugin] Web Hook Provider
|
||||
// TODO: [Plugin] API Endpoint Provider
|
||||
// TODO: [Plugin] Standard Cache Provider
|
||||
// TODO: [Plugin] Reloading/Updating/Disabling
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddRazorPages();
|
||||
|
||||
// Add Responce Cache
|
||||
builder.Services.AddResponseCaching();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
@ -115,6 +117,8 @@ namespace ExtensiblePortfolioSite
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseResponseCaching();
|
||||
|
||||
//app.UseAuthorization(); // not needed
|
||||
|
||||
app.MapRazorPages();
|
||||
|
||||
@ -7,6 +7,13 @@
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:58428;http://localhost:58429"
|
||||
},
|
||||
"Docker": {
|
||||
"commandName": "Docker",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
|
||||
"publishAllPorts": true,
|
||||
"useSSL": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -78,7 +78,6 @@
|
||||
// Caching Options
|
||||
"Cache": {
|
||||
// Lifetimes given in minutes (0 = disabled)
|
||||
"GitCommit": 30, //30m
|
||||
"GitRepo": 120, //2h
|
||||
"GitUser": 1440 //1d
|
||||
}
|
||||
|
||||
@ -147,5 +147,6 @@ namespace GithubPlugin
|
||||
{
|
||||
return httpClient.GetAsync(resourceLocation).Result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user