1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2024-12-16 11:37:58 +02:00

created generic provider factory

This commit is contained in:
kay.one 2013-09-21 22:20:26 -07:00 committed by kayone
parent 0b179a6086
commit 9dbfc6804f
21 changed files with 227 additions and 308 deletions

View File

@ -36,7 +36,7 @@ public class ResourceMappingFixture : TestBase
[TestCase(typeof(Episode), typeof(EpisodeResource))] [TestCase(typeof(Episode), typeof(EpisodeResource))]
[TestCase(typeof(RootFolder), typeof(RootFolderResource))] [TestCase(typeof(RootFolder), typeof(RootFolderResource))]
[TestCase(typeof(NamingConfig), typeof(NamingConfigResource))] [TestCase(typeof(NamingConfig), typeof(NamingConfigResource))]
[TestCase(typeof(Indexer), typeof(IndexerResource))] [TestCase(typeof(IndexerDefinition), typeof(IndexerResource))]
[TestCase(typeof(ReleaseInfo), typeof(ReleaseResource))] [TestCase(typeof(ReleaseInfo), typeof(ReleaseResource))]
[TestCase(typeof(ParsedEpisodeInfo), typeof(ReleaseResource))] [TestCase(typeof(ParsedEpisodeInfo), typeof(ReleaseResource))]
[TestCase(typeof(DownloadDecision), typeof(ReleaseResource))] [TestCase(typeof(DownloadDecision), typeof(ReleaseResource))]

View File

@ -1,9 +1,7 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.ClientSchema; using NzbDrone.Api.ClientSchema;
using NzbDrone.Api.REST;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
using NzbDrone.Core.ThingiProvider;
using Omu.ValueInjecter; using Omu.ValueInjecter;
using FluentValidation; using FluentValidation;
using NzbDrone.Api.Mapping; using NzbDrone.Api.Mapping;
@ -62,47 +60,36 @@ private int CreateIndexer(IndexerResource indexerResource)
private void UpdateIndexer(IndexerResource indexerResource) private void UpdateIndexer(IndexerResource indexerResource)
{ {
var indexer = _indexerService.Get(indexerResource.Id); var indexer = GetIndexer(indexerResource);
indexer.InjectFrom(indexerResource);
indexer.Settings = SchemaDeserializer.DeserializeSchema(indexer.Settings, indexerResource.Fields);
ValidateIndexer(indexer); ValidateIndexer(indexer.Settings);
_indexerService.Update(indexer); _indexerService.Update(indexer);
} }
private static void ValidateIndexer(Indexer indexer) private static void ValidateIndexer(IProviderConfig config)
{ {
if (indexer.Enable) var validationResult = config.Validate();
{
var validationResult = indexer.Settings.Validate();
if (!validationResult.IsValid) if (!validationResult.IsValid)
{ {
throw new ValidationException(validationResult.Errors); throw new ValidationException(validationResult.Errors);
}
} }
} }
private Indexer GetIndexer(IndexerResource indexerResource) private IndexerDefinition GetIndexer(IndexerResource indexerResource)
{ {
var indexer = _indexerService.Schema()
.SingleOrDefault(i =>
i.Implementation.Equals(indexerResource.Implementation,
StringComparison.InvariantCultureIgnoreCase));
if (indexer == null) var definition = new IndexerDefinition();
definition.InjectFrom(indexerResource);
if (indexerResource.Enable)
{ {
throw new BadRequestException("Invalid Indexer Implementation"); ValidateIndexer(definition.Settings);
} }
indexer.InjectFrom(indexerResource); return definition;
indexer.Settings = SchemaDeserializer.DeserializeSchema(indexer.Settings, indexerResource.Fields);
ValidateIndexer(indexer);
return indexer;
} }
private void DeleteIndexer(int id) private void DeleteIndexer(int id)

View File

@ -18,20 +18,22 @@ public IndexerSchemaModule(IIndexerService indexerService)
private List<IndexerResource> GetSchema() private List<IndexerResource> GetSchema()
{ {
var indexers = _indexerService.Schema(); /* var indexers = _indexerService.Schema();
var result = new List<IndexerResource>(indexers.Count); var result = new List<IndexerResource>(indexers.Count);
foreach (var indexer in indexers) foreach (var indexer in indexers)
{ {
var indexerResource = new IndexerResource(); var indexerResource = new IndexerResource();
indexerResource.InjectFrom(indexer); indexerResource.InjectFrom(indexer);
indexerResource.Fields = SchemaBuilder.GenerateSchema(indexer.Settings); indexerResource.Fields = SchemaBuilder.GenerateSchema(indexer.Settings);
result.Add(indexerResource); result.Add(indexerResource);
} }
return result; return result;*/
return null;
} }
} }
} }

View File

@ -57,10 +57,8 @@ public void getting_list_of_indexers()
var indexers = Subject.All().ToList(); var indexers = Subject.All().ToList();
indexers.Should().NotBeEmpty(); indexers.Should().NotBeEmpty();
indexers.Should().NotContain(c => c.Settings == null); indexers.Should().NotContain(c => c.Settings == null);
indexers.Should().NotContain(c => c.Instance == null);
indexers.Should().NotContain(c => c.Name == null); indexers.Should().NotContain(c => c.Name == null);
indexers.Select(c => c.Name).Should().OnlyHaveUniqueItems(); indexers.Select(c => c.Name).Should().OnlyHaveUniqueItems();
indexers.Select(c => c.Instance).Should().OnlyHaveUniqueItems();
} }

View File

@ -48,14 +48,14 @@ public void extv_rss()
public void nzbsorg_rss() public void nzbsorg_rss()
{ {
var indexer = new Newznab(); var indexer = new Newznab();
indexer.Settings = new NewznabSettings
{
ApiKey = "64d61d3cfd4b75e51d01cbc7c6a78275",
Url = "http://nzbs.org"
};
indexer.InstanceDefinition = new IndexerDefinition(); indexer.Definition = new IndexerDefinition();
indexer.InstanceDefinition.Name = "nzbs.org"; indexer.Definition.Name = "nzbs.org";
indexer.Definition.Settings = new NewznabSettings
{
ApiKey = "64d61d3cfd4b75e51d01cbc7c6a78275",
Url = "http://nzbs.org"
};
var result = Subject.FetchRss(indexer); var result = Subject.FetchRss(indexer);

View File

@ -9,7 +9,7 @@
namespace NzbDrone.Core.Test.ThingiProvider namespace NzbDrone.Core.Test.ThingiProvider
{ {
public class ProviderRepositoryFixture : DbTest<IndexerProviderRepository, IndexerDefinition> public class ProviderRepositoryFixture : DbTest<ProviderRepository<IndexerDefinition>, IndexerDefinition>
{ {
[Test] [Test]
public void should_read_write_download_provider() public void should_read_write_download_provider()

View File

@ -132,7 +132,7 @@ public List<DownloadDecision> SeasonSearch(int seriesId, int seasonNumber)
private List<DownloadDecision> Dispatch(Func<IIndexer, IEnumerable<ReleaseInfo>> searchAction, SearchCriteriaBase criteriaBase) private List<DownloadDecision> Dispatch(Func<IIndexer, IEnumerable<ReleaseInfo>> searchAction, SearchCriteriaBase criteriaBase)
{ {
var indexers = _indexerService.GetAvailableIndexers().ToList(); var indexers = _indexerService.GetAvailableProviders().ToList();
var reports = new List<ReleaseInfo>(); var reports = new List<ReleaseInfo>();
_logger.ProgressInfo("Searching {0} indexers for {1}", indexers.Count, criteriaBase); _logger.ProgressInfo("Searching {0} indexers for {1}", indexers.Count, criteriaBase);

View File

@ -1,9 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Indexers.Eztv namespace NzbDrone.Core.Indexers.Eztv
{ {
public class Eztv : IndexerBase public class Eztv : IndexerBase<NullSetting>
{ {
public override string Name public override string Name
{ {

View File

@ -29,7 +29,7 @@ public List<ReleaseInfo> Fetch()
{ {
var result = new List<ReleaseInfo>(); var result = new List<ReleaseInfo>();
var indexers = _indexerService.GetAvailableIndexers().ToList(); var indexers = _indexerService.GetAvailableProviders().ToList();
if (!indexers.Any()) if (!indexers.Any())
{ {

View File

@ -1,23 +1,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Indexers namespace NzbDrone.Core.Indexers
{ {
public interface IIndexer public interface IIndexer : IProvider
{ {
string Name { get; }
bool EnableByDefault { get; }
IEnumerable<IndexerDefinition> DefaultDefinitions { get; }
IndexerDefinition InstanceDefinition { get; set; }
IEnumerable<string> RecentFeed { get; }
IParseFeed Parser { get; } IParseFeed Parser { get; }
IndexerKind Kind { get; } IndexerKind Kind { get; }
IEnumerable<string> RecentFeed { get; }
IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber); IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber);
IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date); IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset); IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset);

View File

@ -4,30 +4,38 @@
namespace NzbDrone.Core.Indexers namespace NzbDrone.Core.Indexers
{ {
public abstract class IndexerBase : IIndexer public abstract class IndexerBase<TSettings> : IIndexer
{ {
public abstract string Name { get; } public abstract string Name { get; }
public abstract IndexerKind Kind { get; } public virtual IEnumerable<ProviderDefinition> DefaultDefinitions
public virtual bool EnableByDefault { get { return true; } }
public IndexerDefinition InstanceDefinition { get; set; }
public virtual IEnumerable<IndexerDefinition> DefaultDefinitions
{ {
get get
{ {
yield return new IndexerDefinition yield return new IndexerDefinition
{ {
Name = Name, Name = Name,
Enable = EnableByDefault, Enable = false,
Implementation = GetType().Name, Implementation = GetType().Name,
Settings = NullSetting.Instance Settings = NullSetting.Instance
}; };
} }
} }
public ProviderDefinition Definition { get; set; }
public abstract IndexerKind Kind { get; }
public virtual bool EnableByDefault { get { return true; } }
protected TSettings Settings
{
get
{
return (TSettings)Definition.Settings;
}
}
public virtual IParseFeed Parser { get; private set; } public virtual IParseFeed Parser { get; private set; }
public abstract IEnumerable<string> RecentFeed { get; } public abstract IEnumerable<string> RecentFeed { get; }

View File

@ -1,11 +1,8 @@
using System; using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Indexers namespace NzbDrone.Core.Indexers
{ {
public class IndexerDefinition : ProviderDefinition public class IndexerDefinition : ProviderDefinition
{ {
public Boolean Enable { get; set; }
} }
} }

View File

@ -1,202 +1,19 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using NLog; using NLog;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Indexers.Newznab;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
using Omu.ValueInjecter;
namespace NzbDrone.Core.Indexers namespace NzbDrone.Core.Indexers
{ {
public class Indexer public interface IIndexerService : IProviderFactory<IIndexer, IndexerDefinition>
{ {
public int Id { get; set; }
public string Name { get; set; }
public bool Enable { get; set; }
public IProviderConfig Settings { get; set; }
public IIndexer Instance { get; set; }
public string Implementation { get; set; }
} }
public interface IIndexerService public class IndexerService : ProviderFactory<IIndexer, IndexerDefinition>
{ {
List<Indexer> All(); public IndexerService(IProviderRepository<IndexerDefinition> providerRepository, IEnumerable<IIndexer> providers, Logger logger)
List<IIndexer> GetAvailableIndexers(); : base(providerRepository, providers, logger)
Indexer Get(int id);
Indexer Get(string name);
List<Indexer> Schema();
Indexer Create(Indexer indexer);
Indexer Update(Indexer indexer);
void Delete(int id);
}
public class IndexerService : IIndexerService, IHandle<ApplicationStartedEvent>
{
private readonly IIndexerRepository _indexerRepository;
private readonly IConfigFileProvider _configFileProvider;
private readonly INewznabTestService _newznabTestService;
private readonly Logger _logger;
private readonly List<IIndexer> _indexers;
public IndexerService(IIndexerRepository indexerRepository,
IEnumerable<IIndexer> indexers,
IConfigFileProvider configFileProvider,
INewznabTestService newznabTestService,
Logger logger)
{ {
_indexerRepository = indexerRepository;
_configFileProvider = configFileProvider;
_newznabTestService = newznabTestService;
_logger = logger;
if (!configFileProvider.Torrent)
{
_indexers = indexers.Where(c => c.Kind != IndexerKind.Torrent).ToList();
}
else
{
_indexers = indexers.ToList();
}
}
public List<Indexer> All()
{
return _indexerRepository.All().Select(ToIndexer).ToList();
}
public List<IIndexer> GetAvailableIndexers()
{
return All().Where(c => c.Enable && c.Settings.Validate().IsValid).Select(c => c.Instance).ToList();
}
public Indexer Get(int id)
{
return ToIndexer(_indexerRepository.Get(id));
}
public Indexer Get(string name)
{
return ToIndexer(_indexerRepository.Get(name));
}
public List<Indexer> Schema()
{
var indexers = new List<Indexer>();
var newznab = new Indexer();
newznab.Instance = new Newznab.Newznab();
newznab.Id = 1;
newznab.Name = "Newznab";
newznab.Settings = new NewznabSettings();
newznab.Implementation = "Newznab";
indexers.Add(newznab);
return indexers;
}
public Indexer Create(Indexer indexer)
{
var definition = new IndexerDefinition
{
Name = indexer.Name,
Enable = indexer.Enable,
Implementation = indexer.Implementation,
Settings = indexer.Settings
};
var instance = ToIndexer(definition).Instance;
_newznabTestService.Test(instance);
definition = _indexerRepository.Insert(definition);
indexer.Id = definition.Id;
return indexer;
}
public Indexer Update(Indexer indexer)
{
var definition = _indexerRepository.Get(indexer.Id);
definition.InjectFrom(indexer);
definition.Settings = indexer.Settings;
_indexerRepository.Update(definition);
return indexer;
}
public void Delete(int id)
{
_indexerRepository.Delete(id);
}
private Indexer ToIndexer(IndexerDefinition definition)
{
var indexer = new Indexer();
indexer.Id = definition.Id;
indexer.Enable = definition.Enable;
indexer.Instance = GetInstance(definition);
indexer.Name = definition.Name;
indexer.Implementation = definition.Implementation;
if (indexer.Instance.GetType().GetMethod("ImportSettingsFromJson") != null)
{
indexer.Settings = ((dynamic)indexer.Instance).ImportSettingsFromJson(definition.Settings);
}
else
{
indexer.Settings = NullSetting.Instance;
}
return indexer;
}
private IIndexer GetInstance(IndexerDefinition indexerDefinition)
{
var type = GetImplementation(indexerDefinition);
var instance = (IIndexer)Activator.CreateInstance(type);
instance.InstanceDefinition = indexerDefinition;
return instance;
}
private Type GetImplementation(IndexerDefinition indexerDefinition)
{
return _indexers.Select(c => c.GetType()).SingleOrDefault(c => c.Name.Equals(indexerDefinition.Implementation, StringComparison.InvariantCultureIgnoreCase));
}
public void Handle(ApplicationStartedEvent message)
{
_logger.Debug("Initializing indexers. Count {0}", _indexers.Count);
RemoveMissingImplementations();
var definitions = _indexers.SelectMany(indexer => indexer.DefaultDefinitions);
var currentIndexer = All();
var newIndexers = definitions.Where(def => currentIndexer.All(c => c.Implementation != def.Implementation)).ToList();
if (newIndexers.Any())
{
_indexerRepository.InsertMany(newIndexers);
}
}
private void RemoveMissingImplementations()
{
var storedIndexers = _indexerRepository.All();
foreach (var indexerDefinition in storedIndexers.Where(i => GetImplementation(i) == null))
{
_logger.Debug("Removing Indexer {0} ", indexerDefinition.Name);
_indexerRepository.Delete(indexerDefinition);
}
} }
} }
} }

View File

@ -1,22 +0,0 @@
using NzbDrone.Common.Serializer;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Indexers
{
public abstract class IndexerWithSetting<TSetting> : IndexerBase where TSetting : class, IProviderConfig, new()
{
public TSetting Settings { get; set; }
public override bool EnableByDefault
{
get { return false; }
}
public TSetting ImportSettingsFromJson(string json)
{
Settings = Json.Deserialize<TSetting>(json) ?? new TSetting();
return Settings;
}
}
}

View File

@ -2,10 +2,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Indexers.Newznab namespace NzbDrone.Core.Indexers.Newznab
{ {
public class Newznab : IndexerWithSetting<NewznabSettings> public class Newznab : IndexerBase<NewznabSettings>
{ {
public override IParseFeed Parser public override IParseFeed Parser
{ {
@ -15,7 +16,7 @@ public override IParseFeed Parser
} }
} }
public override IEnumerable<IndexerDefinition> DefaultDefinitions public override IEnumerable<ProviderDefinition> DefaultDefinitions
{ {
get get
{ {
@ -118,7 +119,7 @@ public override string Name
{ {
get get
{ {
return InstanceDefinition.Name; return Definition.Name;
} }
} }

View File

@ -3,7 +3,7 @@
namespace NzbDrone.Core.Indexers.Omgwtfnzbs namespace NzbDrone.Core.Indexers.Omgwtfnzbs
{ {
public class Omgwtfnzbs : IndexerWithSetting<OmgwtfnzbsSettings> public class Omgwtfnzbs : IndexerBase<OmgwtfnzbsSettings>
{ {
public override string Name public override string Name
{ {

View File

@ -1,9 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Indexers.Wombles namespace NzbDrone.Core.Indexers.Wombles
{ {
public class Wombles : IndexerBase public class Wombles : IndexerBase<NullSetting>
{ {
public override string Name public override string Name
{ {

View File

@ -241,7 +241,6 @@
<Compile Include="Indexers\IIndexer.cs" /> <Compile Include="Indexers\IIndexer.cs" />
<Compile Include="Indexers\IndexerSettingUpdatedEvent.cs" /> <Compile Include="Indexers\IndexerSettingUpdatedEvent.cs" />
<Compile Include="Indexers\NewznabTestService.cs" /> <Compile Include="Indexers\NewznabTestService.cs" />
<Compile Include="Indexers\IndexerWithSetting.cs" />
<Compile Include="Indexers\IParseFeed.cs" /> <Compile Include="Indexers\IParseFeed.cs" />
<Compile Include="Indexers\Newznab\NewznabException.cs" /> <Compile Include="Indexers\Newznab\NewznabException.cs" />
<Compile Include="Indexers\Newznab\NewznabPreProcessor.cs" /> <Compile Include="Indexers\Newznab\NewznabPreProcessor.cs" />
@ -413,13 +412,14 @@
<Compile Include="Parser\Parser.cs" /> <Compile Include="Parser\Parser.cs" />
<Compile Include="Parser\ParsingService.cs" /> <Compile Include="Parser\ParsingService.cs" />
<Compile Include="Parser\QualityParser.cs" /> <Compile Include="Parser\QualityParser.cs" />
<Compile Include="ThingiProvider\ProviderBase.cs" /> <Compile Include="ThingiProvider\IProvider.cs" />
<Compile Include="Qualities\QualityProfileInUseException.cs" /> <Compile Include="Qualities\QualityProfileInUseException.cs" />
<Compile Include="Qualities\QualitySizeRepository.cs" /> <Compile Include="Qualities\QualitySizeRepository.cs" />
<Compile Include="Qualities\QualityProfileRepository.cs" /> <Compile Include="Qualities\QualityProfileRepository.cs" />
<Compile Include="Rest\RestSharpExtensions.cs" /> <Compile Include="Rest\RestSharpExtensions.cs" />
<Compile Include="Rest\RestException.cs" /> <Compile Include="Rest\RestException.cs" />
<Compile Include="SeriesStats\SeriesStatisticsService.cs" /> <Compile Include="SeriesStats\SeriesStatisticsService.cs" />
<Compile Include="ThingiProvider\ProviderService.cs" />
<Compile Include="Tv\EpisodeService.cs" /> <Compile Include="Tv\EpisodeService.cs" />
<Compile Include="Tv\Events\EpisodeInfoDeletedEvent.cs" /> <Compile Include="Tv\Events\EpisodeInfoDeletedEvent.cs" />
<Compile Include="Tv\Events\EpisodeInfoUpdatedEvent.cs" /> <Compile Include="Tv\Events\EpisodeInfoUpdatedEvent.cs" />

View File

@ -1,38 +1,46 @@
 
using System;
using System.Collections.Generic;
using FluentValidation.Results; using FluentValidation.Results;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Notifications;
namespace NzbDrone.Core.ThingiProvider namespace NzbDrone.Core.ThingiProvider
{ {
public class NotificationProviderRepository : BasicRepository<NotificationDefinition> public interface IProviderRepository<TProvider> : IBasicRepository<TProvider> where TProvider : ModelBase, new()
{ {
public NotificationProviderRepository(IDatabase database, IEventAggregator eventAggregator) TProvider GetByName(string name);
: base(database, eventAggregator)
{
}
} }
public class IndexerProviderRepository : BasicRepository<IndexerDefinition> public class ProviderRepository<TProviderDefinition> : BasicRepository<TProviderDefinition>, IProviderRepository<TProviderDefinition>
where TProviderDefinition : ModelBase,
new()
{ {
public IndexerProviderRepository(IDatabase database, IEventAggregator eventAggregator) protected ProviderRepository(IDatabase database, IEventAggregator eventAggregator)
: base(database, eventAggregator) : base(database, eventAggregator)
{ {
} }
public TProviderDefinition GetByName(string name)
{
throw new NotImplementedException();
}
} }
public abstract class ProviderBase public interface IProvider
{ {
public ProviderDefinition Definition { get; set; } string Name { get; }
IEnumerable<ProviderDefinition> DefaultDefinitions { get; }
ProviderDefinition Definition { get; set; }
} }
public abstract class ProviderDefinition : ModelBase public abstract class ProviderDefinition : ModelBase
{ {
public string Name { get; set; } public string Name { get; set; }
public string Implementation { get; set; } public string Implementation { get; set; }
public bool Enable { get; set; }
public string ConfigContract public string ConfigContract
{ {

View File

@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging.Events;
namespace NzbDrone.Core.ThingiProvider
{
public interface IProviderFactory<TProvider, TProviderDefinition>
where TProviderDefinition : ProviderDefinition, new()
where TProvider : IProvider
{
List<TProviderDefinition> All();
List<TProvider> GetAvailableProviders();
TProviderDefinition Get(int id);
//List<TProvider> Schema();
TProviderDefinition Create(TProviderDefinition indexer);
void Update(TProviderDefinition indexer);
void Delete(int id);
}
public abstract class ProviderFactory<TProvider, TProviderDefinition> : IProviderFactory<TProvider, TProviderDefinition>, IHandle<ApplicationStartedEvent>
where TProviderDefinition : ProviderDefinition, new()
where TProvider : IProvider
{
private readonly IProviderRepository<TProviderDefinition> _providerRepository;
private readonly Logger _logger;
private readonly List<TProvider> _providers;
protected ProviderFactory(IProviderRepository<TProviderDefinition> providerRepository, IEnumerable<TProvider> providers, Logger logger)
{
_providerRepository = providerRepository;
_providers = providers.ToList();
_logger = logger;
}
public List<TProviderDefinition> All()
{
return _providerRepository.All().ToList();
}
public List<TProvider> GetAvailableProviders()
{
return All().Where(c => c.Enable && c.Settings.Validate().IsValid)
.Select(GetInstance).ToList();
}
public TProviderDefinition Get(int id)
{
return _providerRepository.Get(id);
}
/* public List<TProvider> Schema()
{
var indexers = new List<Indexer>();
var newznab = new Indexer();
newznab.Instance = new Newznab.Newznab();
newznab.Id = 1;
newznab.Name = "Newznab";
newznab.Settings = new NewznabSettings();
newznab.Implementation = "Newznab";
indexers.Add(newznab);
return indexers;
}*/
public TProviderDefinition Create(TProviderDefinition provider)
{
return _providerRepository.Insert(provider);
}
public void Update(TProviderDefinition definition)
{
_providerRepository.Update(definition);
}
public void Delete(int id)
{
_providerRepository.Delete(id);
}
private TProvider GetInstance(TProviderDefinition definition)
{
var type = GetImplementation(definition);
var instance = (TProvider)Activator.CreateInstance(type);
instance.Definition = definition;
return instance;
}
private Type GetImplementation(TProviderDefinition definition)
{
return _providers.Select(c => c.GetType()).SingleOrDefault(c => c.Name.Equals(definition.Implementation, StringComparison.InvariantCultureIgnoreCase));
}
public void Handle(ApplicationStartedEvent message)
{
_logger.Debug("Initializing Providers. Count {0}", _providers.Count);
RemoveMissingImplementations();
var definitions = _providers.SelectMany(indexer => indexer.DefaultDefinitions);
var currentProviders = All();
var newProviders = definitions.Where(def => currentProviders.All(c => c.Implementation != def.Implementation)).ToList();
if (newProviders.Any())
{
_providerRepository.InsertMany(newProviders.Cast<TProviderDefinition>().ToList());
}
}
private void RemoveMissingImplementations()
{
var storedProvider = _providerRepository.All();
foreach (var providerDefinition in storedProvider.Where(i => GetImplementation(i) == null))
{
_logger.Debug("Removing {0} ", providerDefinition.Name);
_providerRepository.Delete(providerDefinition);
}
}
}
}

View File

@ -7,7 +7,7 @@
<FrameworkUtilisationTypeForGallio>Disabled</FrameworkUtilisationTypeForGallio> <FrameworkUtilisationTypeForGallio>Disabled</FrameworkUtilisationTypeForGallio>
<FrameworkUtilisationTypeForMSpec>Disabled</FrameworkUtilisationTypeForMSpec> <FrameworkUtilisationTypeForMSpec>Disabled</FrameworkUtilisationTypeForMSpec>
<FrameworkUtilisationTypeForMSTest>Disabled</FrameworkUtilisationTypeForMSTest> <FrameworkUtilisationTypeForMSTest>Disabled</FrameworkUtilisationTypeForMSTest>
<EngineModes>Run all tests automatically:BFRydWU=;Run all tests manually:BUZhbHNl;Run impacted tests automatically, others manually (experimental!):CklzSW1wYWN0ZWQ=;Run pinned tests automatically, others manually:CElzUGlubmVk;Fast:DlN0cnVjdHVyYWxOb2RlBAAAABNEb2VzTm90SGF2ZUNhdGVnb3J5D0ludGVncmF0aW9uVGVzdBNEb2VzTm90SGF2ZUNhdGVnb3J5BkRiVGVzdApJc0ltcGFjdGVkE0RvZXNOb3RIYXZlQ2F0ZWdvcnkORGlza0FjY2Vzc1Rlc3QAAAAAAAAAAAAAAAA=</EngineModes> <EngineModes>Run all tests automatically:BFRydWU=;Run all tests manually:BUZhbHNl;Run impacted tests automatically, others manually (experimental!):CklzSW1wYWN0ZWQ=;Run pinned tests automatically, others manually:CElzUGlubmVk;Fast:DlN0cnVjdHVyYWxOb2RlBQAAABNEb2VzTm90SGF2ZUNhdGVnb3J5D0ludGVncmF0aW9uVGVzdBNEb2VzTm90SGF2ZUNhdGVnb3J5BkRiVGVzdApJc0ltcGFjdGVkE0RvZXNOb3RIYXZlQ2F0ZWdvcnkORGlza0FjY2Vzc1Rlc3QISXNQaW5uZWQAAAAAAAAAAAAAAAABAAAA</EngineModes>
<MetricsExclusionList> <MetricsExclusionList>
</MetricsExclusionList> </MetricsExclusionList>
</SolutionConfiguration> </SolutionConfiguration>