Skip to content

Commit

Permalink
proof of concept for wikibus/Argolis#4
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Nov 29, 2016
1 parent b469585 commit 9ed8c15
Show file tree
Hide file tree
Showing 20 changed files with 309 additions and 41 deletions.
139 changes: 139 additions & 0 deletions src/Argolis.Templates/Argolis.Templates.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EAFD448E-B765-4856-82DC-9C46BEA87EF5}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Argolis.Templates</RootNamespace>
<AssemblyName>Argolis.Templates</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisRuleSet>..\..\paket-files\tpluscode\a285267d2543466fc35c3a168c846f9f\NoDocumentation.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ArgolisModule.cs" />
<Compile Include="IdentifierOf.cs" />
<Compile Include="IdentifierTemplateAttribute.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="paket.references" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1' Or $(TargetFrameworkVersion) == 'v4.6.2' Or $(TargetFrameworkVersion) == 'v4.6.3')">
<ItemGroup>
<Reference Include="Microsoft.DotNet.PlatformAbstractions">
<HintPath>..\..\packages\Microsoft.DotNet.PlatformAbstractions\lib\net451\Microsoft.DotNet.PlatformAbstractions.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1' Or $(TargetFrameworkVersion) == 'v4.6.2' Or $(TargetFrameworkVersion) == 'v4.6.3')">
<ItemGroup>
<Reference Include="Microsoft.Extensions.DependencyModel">
<HintPath>..\..\packages\Microsoft.Extensions.DependencyModel\lib\net451\Microsoft.Extensions.DependencyModel.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1' Or $(TargetFrameworkVersion) == 'v4.6.2' Or $(TargetFrameworkVersion) == 'v4.6.3')">
<ItemGroup>
<Reference Include="Nancy">
<HintPath>..\..\packages\Nancy\lib\net452\Nancy.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1' Or $(TargetFrameworkVersion) == 'v4.6.2' Or $(TargetFrameworkVersion) == 'v4.6.3')">
<ItemGroup>
<Reference Include="Nancy.Routing.UriTemplates">
<HintPath>..\..\packages\Nancy.Routing.UriTemplates\lib\net452\Nancy.Routing.UriTemplates.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1' Or $(TargetFrameworkVersion) == 'v4.6.2' Or $(TargetFrameworkVersion) == 'v4.6.3')">
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\packages\Newtonsoft.Json\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<ItemGroup>
<Analyzer Include="..\..\packages\StyleCop.Analyzers\analyzers\dotnet\cs\Newtonsoft.Json.dll">
<Paket>True</Paket>
</Analyzer>
<Analyzer Include="..\..\packages\StyleCop.Analyzers\analyzers\dotnet\cs\StyleCop.Analyzers.CodeFixes.dll">
<Paket>True</Paket>
</Analyzer>
<Analyzer Include="..\..\packages\StyleCop.Analyzers\analyzers\dotnet\cs\StyleCop.Analyzers.dll">
<Paket>True</Paket>
</Analyzer>
</ItemGroup>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1' Or $(TargetFrameworkVersion) == 'v4.6.2' Or $(TargetFrameworkVersion) == 'v4.6.3')">
<ItemGroup>
<Reference Include="TunnelVisionLabs.Net.UriTemplate">
<HintPath>..\..\packages\TunnelVisionLabs.Net.UriTemplate\lib\net20\TunnelVisionLabs.Net.UriTemplate.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
</Project>
18 changes: 18 additions & 0 deletions src/Argolis.Templates/ArgolisModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Reflection;

namespace Argolis.Templates
{
public class ArgolisModule : Nancy.Routing.UriTemplates.UriTemplateModule
{
public virtual void Get<T>(Func<dynamic, dynamic> action)
{
this.Get<dynamic>(GetModelTemplate(typeof(T)), action);
}

private static string GetModelTemplate(Type type)
{
return type.GetCustomAttribute<IdentifierTemplateAttribute>().Template;
}
}
}
63 changes: 63 additions & 0 deletions src/Argolis.Templates/IdentifierOf.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using TunnelVisionLabs.Net;

namespace Argolis.Templates
{
public static class IdentifierOf<T>
{
public static IdentifierMatches Match(Uri uri, string baseUri = null)
{
var matches = new Dictionary<string, object>();
var templateStr = typeof(T).GetCustomAttribute<IdentifierTemplateAttribute>().Template;
var template = new UriTemplate(baseUri + templateStr);

uri = new Uri(Uri.EscapeUriString(uri.ToString()));
var templateMatch = template.Match(uri);

if (templateMatch != null)
{
matches = templateMatch.Bindings.ToDictionary(m => m.Key, m => m.Value.Value);
}

return new IdentifierMatches(matches);
}

public static Uri Bind(Dictionary<string, object> dictionary, string baseUri = null)
{
var templateStr = typeof(T).GetCustomAttribute<IdentifierTemplateAttribute>().Template;
var template = new UriTemplate(baseUri + templateStr);

return template.BindByName(dictionary);
}

public class IdentifierMatches
{
private readonly Dictionary<string, object> dictionary;

public IdentifierMatches(Dictionary<string, object> dictionary)
{
this.dictionary = dictionary;
}

public TOut Get<TOut>(string key)
{
var valueType = Nullable.GetUnderlyingType(typeof(TOut));

if (valueType == null)
{
valueType = typeof(TOut);
}

if (this.dictionary.ContainsKey(key))
{
return (TOut)Convert.ChangeType(this.dictionary[key], valueType);
}

return default(TOut);
}
}
}
}
15 changes: 15 additions & 0 deletions src/Argolis.Templates/IdentifierTemplateAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;

namespace Argolis.Templates
{
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class IdentifierTemplateAttribute : Attribute
{
public IdentifierTemplateAttribute(string template)
{
this.Template = template;
}

public string Template { get; private set; }
}
}
16 changes: 16 additions & 0 deletions src/Argolis.Templates/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Reflection;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle("Argolis.Templates")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Argolis.Templates")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: Guid("eafd448e-b765-4856-82dc-9c46bea87ef5")]

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
3 changes: 3 additions & 0 deletions src/Argolis.Templates/paket.references
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
StyleCop.Analyzers
Nancy.Routing.UriTemplates
TunnelVisionLabs.Net.UriTemplate
8 changes: 7 additions & 1 deletion src/wikibus.sources.EF/EntityFactory.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Argolis.Templates;
using Wikibus.Common;

namespace Wikibus.Sources.EF
Expand Down Expand Up @@ -67,7 +68,12 @@ public Brochure CreateBrochure(EntityWrapper<BrochureEntity> source)
{
var target = new Brochure
{
Id = this.templates.CreateBrochureIdentifier(source.Entity.Id)
Id = IdentifierOf<Brochure>.Bind(
new Dictionary<string, object>
{
["id"] = source.Entity.Id
},
this.configuration.BaseResourceNamespace)
};
if (source.Entity.Notes != null)
{
Expand Down
13 changes: 0 additions & 13 deletions src/wikibus.sources.EF/IdRetriever.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,6 @@ public IdRetriever(IdentifierTemplates configuration)
this.configuration = configuration;
}

[return: AllowNull]
public int? GetBrochureId(Uri uri)
{
var uriTemplateMatch = this.configuration.GetMatch<Brochure>(uri);
if (uriTemplateMatch.ContainsKey("id"))
{
var binding = uriTemplateMatch["id"];
return Convert.ToInt32(binding.ToString());
}

return null;
}

[return: AllowNull]
public int? GetBookId(Uri uri)
{
Expand Down
8 changes: 6 additions & 2 deletions src/wikibus.sources.EF/SourcesRepository.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Linq;
using Argolis.Templates;
using Hydra.Resources;
using NullGuard;
using Wikibus.Common;
using Wikibus.Sources.Filters;

namespace Wikibus.Sources.EF
Expand All @@ -11,12 +13,14 @@ public class SourcesRepository : ISourcesRepository
private readonly ISourceContext context;
private readonly IdRetriever identifierRetriever;
private readonly EntityFactory factory;
private readonly IWikibusConfiguration config;

public SourcesRepository(ISourceContext context, IdRetriever identifierRetriever, EntityFactory factory)
public SourcesRepository(ISourceContext context, IdRetriever identifierRetriever, EntityFactory factory, IWikibusConfiguration config)
{
this.context = context;
this.identifierRetriever = identifierRetriever;
this.factory = factory;
this.config = config;
}

[return: AllowNull]
Expand Down Expand Up @@ -44,7 +48,7 @@ public Magazine GetMagazine(Uri identifier)
[return: AllowNull]
public Brochure GetBrochure(Uri identifier)
{
var id = this.identifierRetriever.GetBrochureId(identifier);
var id = IdentifierOf<Brochure>.Match(identifier, this.config.BaseResourceNamespace).Get<int?>("id");

if (id == null)
{
Expand Down
4 changes: 4 additions & 0 deletions src/wikibus.sources.EF/wikibus.sources.EF.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Argolis.Templates\Argolis.Templates.csproj">
<Project>{EAFD448E-B765-4856-82DC-9C46BEA87EF5}</Project>
<Name>Argolis.Templates</Name>
</ProjectReference>
<ProjectReference Include="..\wikibus.common\wikibus.common.csproj">
<Project>{5BE7E665-DA3B-4238-BC5B-8D722D27F5C4}</Project>
<Name>wikibus.common</Name>
Expand Down
7 changes: 3 additions & 4 deletions src/wikibus.sources.nancy/SourcesModule.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using System;
using System.Collections.Generic;
using Argolis.Templates;
using Hydra.Resources;
using Nancy;
using Nancy.ModelBinding;
using Nancy.Responses.Negotiation;
using Nancy.Routing.UriTemplates;
using TunnelVisionLabs.Net;
using Wikibus.Common;
using Wikibus.Sources.Filters;
Expand All @@ -15,7 +14,7 @@ namespace Wikibus.Sources.Nancy
/// <summary>
/// Module, which serves <see cref="Source"/>s
/// </summary>
public sealed class SourcesModule : UriTemplateModule
public sealed class SourcesModule : ArgolisModule
{
private const int PageSize = 12;

Expand All @@ -32,7 +31,7 @@ public SourcesModule(ISourcesRepository repository, IWikibusConfiguration config

this.ReturnNotFoundWhenModelIsNull();

this.Get(Id.BrochurePath, r => this.GetSingle(repository.GetBrochure));
this.Get<Brochure>(r => this.GetSingle(repository.GetBrochure));
this.Get(Id.BookPath, r => this.GetSingle(repository.GetBook));
this.Get(Id.MagazinePath, r => this.GetSingle(repository.GetMagazine));
this.Get(Id.MagazineIssuesPath, r => this.GetSingle(repository.GetMagazineIssues, new Collection<Issue>()));
Expand Down

0 comments on commit 9ed8c15

Please sign in to comment.