Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed #71 and added functional non-ioc sample #72

Merged
merged 12 commits into from
Dec 5, 2017
Merged
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ dotnet: 2.0.0
dist: trusty
script:
- dotnet build Botwin.sln
- dotnet test test
- dotnet test test/Botwin.Samples.Tests/Botwin.Samples.Tests.csproj
- dotnet test test/Botwin.Tests/Botwin.Tests.csproj
- dotnet pack src
19 changes: 17 additions & 2 deletions Botwin.sln
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@


Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2002
Expand All @@ -13,12 +13,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{35DE
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{DCB5B9A0-F06D-4BDF-917D-A459C790C718}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Botwin.Tests", "test\Botwin.Tests.csproj", "{32E3C950-F6C1-4635-B87F-0EA30044E2F4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Botwin.Tests", "test\Botwin.Tests\Botwin.Tests.csproj", "{32E3C950-F6C1-4635-B87F-0EA30044E2F4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "template", "template", "{47344C99-29DA-410E-AFC2-8FD3BA6727DB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotwinTemplate", "template\content\BotwinTemplate.csproj", "{572762BB-5DFF-425F-8F66-500B973DBB0E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Botwin.Samples.Tests", "test\Botwin.Samples.Tests\Botwin.Samples.Tests.csproj", "{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -77,6 +79,18 @@ Global
{572762BB-5DFF-425F-8F66-500B973DBB0E}.Release|x64.Build.0 = Release|Any CPU
{572762BB-5DFF-425F-8F66-500B973DBB0E}.Release|x86.ActiveCfg = Release|Any CPU
{572762BB-5DFF-425F-8F66-500B973DBB0E}.Release|x86.Build.0 = Release|Any CPU
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}.Debug|x64.ActiveCfg = Debug|x64
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}.Debug|x64.Build.0 = Debug|x64
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}.Debug|x86.ActiveCfg = Debug|x86
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}.Debug|x86.Build.0 = Debug|x86
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}.Release|Any CPU.Build.0 = Release|Any CPU
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}.Release|x64.ActiveCfg = Release|x64
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}.Release|x64.Build.0 = Release|x64
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}.Release|x86.ActiveCfg = Release|x86
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -86,6 +100,7 @@ Global
{2C511F74-490A-4804-A826-DC9626C669E9} = {35DE35A0-758D-4FDD-BDA3-67F04F65677D}
{32E3C950-F6C1-4635-B87F-0EA30044E2F4} = {DCB5B9A0-F06D-4BDF-917D-A459C790C718}
{572762BB-5DFF-425F-8F66-500B973DBB0E} = {47344C99-29DA-410E-AFC2-8FD3BA6727DB}
{DD5E942A-D546-489B-A5E9-8CB42C61BEC1} = {DCB5B9A0-F06D-4BDF-917D-A459C790C718}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9096DE78-6327-48BA-AE0E-336F769681A7}
Expand Down
6 changes: 6 additions & 0 deletions Botwin.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_CODE/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/REDUNDANT_THIS_QUALIFIER_STYLE/@EntryValue">ALWAYS_USE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_EMBEDDED_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
Expand All @@ -50,7 +52,11 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters /&gt;&lt;/data&gt;</s:String>
Expand Down
7 changes: 7 additions & 0 deletions samples/AppConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace BotwinSample
{
public class AppConfiguration
{
public static string ConnectionString { get; set; }
}
}
3 changes: 2 additions & 1 deletion samples/BotwinSample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.0.0" />
</ItemGroup>
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Botwin.Samples.CreateDirector
{
public class CreateDirectorRoute
{
public delegate int CreateDirector(Director director);

public static int Handle(Director director, CreateDirector createDirector)
{
return createDirector(director);
}
}
}
7 changes: 7 additions & 0 deletions samples/Features/FunctionalProgramming/Director.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Botwin.Samples
{
public class Director
{
public string Name { get; set; }
}
}
11 changes: 11 additions & 0 deletions samples/Features/FunctionalProgramming/DirectorValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Botwin.Samples
{
using FluentValidation;
public class DirectorValidator : AbstractValidator<Director>
{
public DirectorValidator()
{
this.RuleFor(x => x.Name).NotEmpty();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
namespace Botwin.Samples
{
using Botwin.ModelBinding;
using Botwin.Request;
using Botwin.Response;
using Microsoft.AspNetCore.Routing;

public class FunctionalProgrammingModule : BotwinModule
{
public FunctionalProgrammingModule() : base("/functional")
{
this.Get("/directors", async (req, res, routeData) =>
{
var handler = RouteHandlers.ListDirectorsHandler;

var actor = handler?.Invoke();

if (actor == null)
{
res.StatusCode = 401;
return;
}

await res.AsJson(actor);
});

this.Get("/directors/{id:int}", async (req, res, routeData) =>
{
var handler = RouteHandlers.GetDirectorByIdHandler;

var director = handler?.Invoke(routeData.As<int>("id"));

await res.AsJson(director);
});

this.Post("/directors", async (req, res, routeData) =>
{
var result = req.BindAndValidate<Director>();

if (!result.ValidationResult.IsValid)
{
res.StatusCode = 422;
await res.Negotiate(result.ValidationResult.GetFormattedErrors());
return;
}

var handler = RouteHandlers.CreateDirectorHandler;

var id = handler.Invoke(result.Data);

res.StatusCode = 201;
res.Headers["Location"] = "/" + id;
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Botwin.Samples.GetDirectorById
{
public class GetDirectorByIdRoute
{
public delegate Director GetDirectorById(int id);

public delegate bool UserAllowed();

public static Director Handle(int id, GetDirectorById getDirectorById, UserAllowed userAllowed)
{
var currentUserAllowed = userAllowed();
if (!currentUserAllowed)
{
return null;
}

var director = getDirectorById(id);
return director;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Botwin.Samples
{
using System.Collections.Generic;

public static class GetDirectorsRoute
{
public delegate IEnumerable<Director> ListDirectors();
public delegate bool UserAllowed();

public static IEnumerable<Director> Handle(ListDirectors listDirectors, UserAllowed userAllowed)
{
var currentUserAllowed = userAllowed();
if (!currentUserAllowed)
{
return null;
}

var directors = listDirectors();
return directors;
}
}
}
46 changes: 46 additions & 0 deletions samples/Features/FunctionalProgramming/RouteHandlers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
namespace Botwin.Samples
{
using System;
using Botwin.Samples.CreateDirector;
using Botwin.Samples.GetDirectorById;
using BotwinSample;

public static class RouteHandlers
{
private static GetDirectorsRoute.ListDirectors listDirectors;

private static GetDirectorByIdRoute.GetDirectorById getDirectorById;

private static CreateDirectorRoute.CreateDirector createDirector;

public static GetDirectorsRoute.ListDirectors ListDirectorsHandler
{
get
{
return listDirectors ?? (() => GetDirectorsRoute.Handle(listDirectors: () =>
{
Console.WriteLine($"Getting sql connection from settings {AppConfiguration.ConnectionString} as an example of how you'd get app settings");
return new[] { new Director() };
}, userAllowed: () => true));
}

set => listDirectors = value;
}

public static GetDirectorByIdRoute.GetDirectorById GetDirectorByIdHandler
{
get { return getDirectorById ?? (dirId => GetDirectorByIdRoute.Handle(dirId, id => new Director(), () => true)); }
set => getDirectorById = value;
}

public static CreateDirectorRoute.CreateDirector CreateDirectorHandler
{
get { return createDirector ?? (director => CreateDirectorRoute.Handle(director, newDirector =>
{
//Create database connection here and store in the database
return 1123;
})); }
set => createDirector = value;
}
}
}
File renamed without changes.
File renamed without changes.
18 changes: 5 additions & 13 deletions samples/Program.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
namespace Botwin.Samples
{
using System;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

class Program
{
static void Main(string[] args)
{
using (var host = new WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseKestrel()
.UseStartup<Startup>()
.UseUrls("http://*:5000")
.Build())
{
Console.WriteLine("Starting application...");
host.Run();
}
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build()
.Run();
}
}
}
12 changes: 9 additions & 3 deletions samples/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
namespace Botwin.Samples
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using BotwinSample;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

public class Startup
Expand All @@ -14,8 +17,11 @@ public void ConfigureServices(IServiceCollection services)
services.AddBotwin();
}

public void Configure(IApplicationBuilder app)
public void Configure(IApplicationBuilder app, IConfiguration config)
{
var appconfig = new AppConfiguration();
config.Bind(appconfig);

app.UseExceptionHandler("/errorhandler");

app.UseBotwin(this.GetOptions());
Expand All @@ -28,7 +34,7 @@ private BotwinOptions GetOptions()

private Task<bool> GetBeforeHook(HttpContext ctx)
{
ctx.Request.Headers.Add("HOWDY", "FOLKS");
ctx.Request.Headers["HOWDY"] = "FOLKS";
return Task.FromResult(true);
}

Expand All @@ -38,4 +44,4 @@ private Task GetAfterHook(HttpContext ctx)
return Task.CompletedTask;
}
}
}
}
3 changes: 3 additions & 0 deletions samples/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"connectionString" :"mydb"
}
2 changes: 1 addition & 1 deletion src/BotwinExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ private static void ApplyGlobalBeforeHook(IApplicationBuilder builder, BotwinOpt
/// <param name="assemblies">Optional array of <see cref="Assembly"/> to add to the services collection. If assemblies are not provided, Assembly.GetEntryAssembly is called.</param>
public static void AddBotwin(this IServiceCollection services, params Assembly[] assemblies)
{
assemblies = assemblies.Any() ? assemblies : new[] { Assembly.GetEntryAssembly() };
assemblies = assemblies.Any() ? assemblies : new[] { Assembly.GetCallingAssembly() };

var validators = assemblies.SelectMany(ass => ass.GetExportedTypes())
.Where(typeof(IValidator).IsAssignableFrom)
Expand Down
17 changes: 17 additions & 0 deletions test/Botwin.Samples.Tests/Botwin.Samples.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<ProjectReference Include="../../samples/BotwinSample.csproj" />
<None Include="../../samples/appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
Loading