From 0f7ecfb36cf2eae7f8d4ea0403c96afffcf492ee Mon Sep 17 00:00:00 2001 From: Biarity Date: Sat, 27 Jan 2018 15:20:57 +1000 Subject: [PATCH] Basic working & complete tests --- Sieve/Attributes/SieveAttribute.cs | 2 +- Sieve/Extensions/OrderByDynamic.cs | 27 ++++ Sieve/Extensions/OrderByWithDirection.cs | 31 ---- Sieve/Models/FilterTerm.cs | 39 ++++- Sieve/Models/SieveModel.cs | 49 +++++- Sieve/Models/SortTerm.cs | 37 ++++- Sieve/Services/ISieveProcessor.cs | 16 ++ Sieve/Services/SieveProcessor.cs | 143 ++++++++++++------ Sieve/Sieve.csproj | 2 - SieveTests/Controllers/TestController.cs | 55 +++++++ SieveTests/Controllers/ValuesController.cs | 44 ------ SieveTests/Entities/ApplicationDbContext.cs | 20 +++ SieveTests/Entities/Post.cs | 25 +++ .../20180127005347_Init.Designer.cs | 44 ++++++ SieveTests/Migrations/20180127005347_Init.cs | 35 +++++ .../ApplicationDbContextModelSnapshot.cs | 43 ++++++ SieveTests/Program.cs | 4 +- SieveTests/Properties/launchSettings.json | 5 +- SieveTests/SieveTests.csproj | 9 ++ SieveTests/Startup.cs | 14 ++ SieveTests/appsettings.json | 6 + 21 files changed, 509 insertions(+), 141 deletions(-) create mode 100644 Sieve/Extensions/OrderByDynamic.cs delete mode 100644 Sieve/Extensions/OrderByWithDirection.cs create mode 100644 Sieve/Services/ISieveProcessor.cs create mode 100644 SieveTests/Controllers/TestController.cs delete mode 100644 SieveTests/Controllers/ValuesController.cs create mode 100644 SieveTests/Entities/ApplicationDbContext.cs create mode 100644 SieveTests/Entities/Post.cs create mode 100644 SieveTests/Migrations/20180127005347_Init.Designer.cs create mode 100644 SieveTests/Migrations/20180127005347_Init.cs create mode 100644 SieveTests/Migrations/ApplicationDbContextModelSnapshot.cs diff --git a/Sieve/Attributes/SieveAttribute.cs b/Sieve/Attributes/SieveAttribute.cs index 019a759..cb623b8 100644 --- a/Sieve/Attributes/SieveAttribute.cs +++ b/Sieve/Attributes/SieveAttribute.cs @@ -5,7 +5,7 @@ using System.Text; namespace Sieve.Attributes { [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] - class SieveAttribute : Attribute + public class SieveAttribute : Attribute { /// /// Override name used diff --git a/Sieve/Extensions/OrderByDynamic.cs b/Sieve/Extensions/OrderByDynamic.cs new file mode 100644 index 0000000..af39976 --- /dev/null +++ b/Sieve/Extensions/OrderByDynamic.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace Sieve.Extensions +{ + public static partial class LinqExtentions + { + public static IQueryable OrderByDynamic(this IQueryable source, string orderByProperty, + bool desc, bool useThenBy) + { + string command = desc ? + ( useThenBy ? "ThenByDescending" : "OrderByDescending") : + ( useThenBy ? "ThenBy" : "OrderBy"); + var type = typeof(TEntity); + var property = type.GetProperty(orderByProperty); + var parameter = Expression.Parameter(type, "p"); + var propertyAccess = Expression.MakeMemberAccess(parameter, property); + var orderByExpression = Expression.Lambda(propertyAccess, parameter); + var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType }, + source.Expression, Expression.Quote(orderByExpression)); + return source.Provider.CreateQuery(resultExpression); + } + } +} diff --git a/Sieve/Extensions/OrderByWithDirection.cs b/Sieve/Extensions/OrderByWithDirection.cs deleted file mode 100644 index 5521ee7..0000000 --- a/Sieve/Extensions/OrderByWithDirection.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; - -namespace Sieve.Extensions -{ - - public static class LinqExtensions - { - public static IOrderedEnumerable OrderByWithDirection - (this IEnumerable source, - Func keySelector, - bool descending) - { - return descending ? source.OrderByDescending(keySelector) - : source.OrderBy(keySelector); - } - - public static IOrderedQueryable OrderByWithDirection - (this IQueryable source, - Expression> keySelector, - bool descending) - { - return descending ? source.OrderByDescending(keySelector) - : source.OrderBy(keySelector); - } - - } -} diff --git a/Sieve/Models/FilterTerm.cs b/Sieve/Models/FilterTerm.cs index ca28198..8afe827 100644 --- a/Sieve/Models/FilterTerm.cs +++ b/Sieve/Models/FilterTerm.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using Microsoft.AspNetCore.Mvc.ModelBinding; using System.ComponentModel.DataAnnotations; using System.Text; @@ -8,13 +7,40 @@ namespace Sieve.Models { public class FilterTerm { - public string Name { get; set; } + private string _filter; - public string Operator { get; set; } + public FilterTerm(string filter) + { + _filter = filter; + } + + public string Name + { + get + { + return _filter.Split(' ')[0]; + } + } + + public string Operator + { + get + { + return _filter.Split(' ')[1]; + } + } + + + public string Value { + get + { + return _filter.Split(' ')[2]; + } + } - [BindNever] public FilterOperator OperatorParsed { - get { + get + { switch (Operator.Trim().ToLower()) { case "equals": @@ -51,8 +77,5 @@ namespace Sieve.Models } } - public string Value { get; set; } - - public bool Descending { get; set; } = false; } } \ No newline at end of file diff --git a/Sieve/Models/SieveModel.cs b/Sieve/Models/SieveModel.cs index 646b08f..f1ac7d7 100644 --- a/Sieve/Models/SieveModel.cs +++ b/Sieve/Models/SieveModel.cs @@ -7,14 +7,55 @@ namespace Sieve.Models { public class SieveModel { - public IEnumerable Filter { get; set; } + public string Filters { get; set; } - public IEnumerable Sort { get; set; } + public string Sorts { get; set; } [Range(1, Double.MaxValue)] - public int Page { get; set; } = 1; + public int? Page { get; set; } [Range(1, Double.MaxValue)] - public int PageSize { get; set; } = 10; + public int? PageSize { get; set; } + + + public List FilterParsed + { + get + { + if (Filters != null) + { + var value = new List(); + foreach (var filter in Filters.Split(',')) + { + value.Add(new FilterTerm(filter)); + } + return value; + } + else + { + return null; + } + } + } + + public List SortParsed + { + get + { + if (Sorts != null) + { + var value = new List(); + foreach (var sort in Sorts.Split(',')) + { + value.Add(new SortTerm(sort)); + } + return value; + } + else + { + return null; + } + } + } } } diff --git a/Sieve/Models/SortTerm.cs b/Sieve/Models/SortTerm.cs index 86f9b42..a95de9f 100644 --- a/Sieve/Models/SortTerm.cs +++ b/Sieve/Models/SortTerm.cs @@ -7,8 +7,41 @@ namespace Sieve.Models { public class SortTerm { - public string Name { get; set; } + private string _sort; - public bool Descending { get; set; } = false; + public SortTerm(string sort) + { + _sort = sort; + } + + public string Name + { + get + { + if (_sort.StartsWith('-')) + { + return _sort.Substring(1); + } + else + { + return _sort; + } + } + } + + public bool Descending + { + get + { + if (_sort.StartsWith('-')) + { + return true; + } + else + { + return false; + } + } + } } } \ No newline at end of file diff --git a/Sieve/Services/ISieveProcessor.cs b/Sieve/Services/ISieveProcessor.cs new file mode 100644 index 0000000..d3d9f27 --- /dev/null +++ b/Sieve/Services/ISieveProcessor.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using System.Linq; +using Sieve.Models; + +namespace Sieve.Services +{ + //public interface ISieveProcessor : ISieveProcessor { } + + public interface ISieveProcessor where TEntity : class + { + IQueryable ApplyAll(SieveModel model, IQueryable source); + IQueryable ApplySorting(SieveModel model, IQueryable result); + IQueryable ApplyFiltering(SieveModel model, IQueryable result); + IQueryable ApplyPagination(SieveModel model, IQueryable result); + } +} \ No newline at end of file diff --git a/Sieve/Services/SieveProcessor.cs b/Sieve/Services/SieveProcessor.cs index fe05640..f57ee3f 100644 --- a/Sieve/Services/SieveProcessor.cs +++ b/Sieve/Services/SieveProcessor.cs @@ -5,19 +5,34 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using System.Data.Entity; using System.Reflection; using Sieve.Attributes; using Sieve.Extensions; +using System.ComponentModel; +using System.Collections; +using System.Linq.Expressions; namespace Sieve.Services { - public class SieveProcessor + //public class SieveProcessor : SieveProcessor, ISieveProcessor + //{ + // public SieveProcessor(IOptions options, ISieveCustomSortMethods customSortMethods, ISieveCustomFilterMethods customFilterMethods) : base(options, customSortMethods, customFilterMethods) + // { + // } + // + // public SieveProcessor(IOptions options) : base(options) + // { + // } + // + //} + + public class SieveProcessor : ISieveProcessor where TEntity: class { private IOptions _options; private ISieveCustomSortMethods _customSortMethods; private ISieveCustomFilterMethods _customFilterMethods; + public SieveProcessor(IOptions options, ISieveCustomSortMethods customSortMethods, @@ -28,15 +43,23 @@ namespace Sieve.Services _customFilterMethods = customFilterMethods; } - public IEnumerable ApplyAll(SieveModel model, IQueryable source) + public SieveProcessor(IOptions options) { - var result = source.AsNoTracking(); + _options = options; + } + + public IQueryable ApplyAll(SieveModel model, IQueryable source) + { + var result = source; + + if (model == null) + return result; // Sort - result = ApplySort(model, result); + result = ApplySorting(model, result); // Filter - result = ApplyFilter(model, result); + result = ApplyFiltering(model, result); // Paginate result = ApplyPagination(model, result); @@ -44,84 +67,95 @@ namespace Sieve.Services return result; } - public IQueryable ApplySort(SieveModel model, IQueryable result) + public IQueryable ApplySorting(SieveModel model, IQueryable result) { - foreach (var sortTerm in model.Sort) + if (model?.SortParsed == null) + return result; + + var useThenBy = false; + foreach (var sortTerm in model.SortParsed) { var property = GetSieveProperty(true, false, sortTerm.Name); if (property != null) { - result = result.OrderByWithDirection( - e => property.GetValue(e), - sortTerm.Descending); + result = result.OrderByDynamic(property.Name, sortTerm.Descending, useThenBy); } else { - var customMethod = _customSortMethods.GetType() - .GetMethod(sortTerm.Name); - - if (customMethod != null) - { - result = result.OrderByWithDirection( - e => customMethod.Invoke(_customSortMethods, new object[] { e }), - sortTerm.Descending); - } + result = ApplyCustomMethod(result, sortTerm.Name, _customSortMethods, + includeUseThenBy: true, + useThenBy: useThenBy); } + useThenBy = true; } return result; } - - public IQueryable ApplyFilter(SieveModel model, IQueryable result) + + public IQueryable ApplyFiltering(SieveModel model, IQueryable result) { - foreach (var filterTerm in model.Filter) + if (model?.FilterParsed == null) + return result; + + foreach (var filterTerm in model.FilterParsed) { var property = GetSieveProperty(false, true, filterTerm.Name); if (property != null) { - var filterValue = Convert.ChangeType(filterTerm.Value, property.GetType()); - + var converter = TypeDescriptor.GetConverter(property.PropertyType); + var parameter = Expression.Parameter(typeof(TEntity), "e"); + + var filterValue = Expression.Constant( + converter.CanConvertFrom(typeof(string)) ? + converter.ConvertFrom(filterTerm.Value) : + Convert.ChangeType(filterTerm.Value, property.PropertyType)); + + var propertyValue = Expression.PropertyOrField(parameter, property.Name); + + Expression comparison; + switch (filterTerm.OperatorParsed) { case FilterOperator.Equals: - result = result.Where(e => ((IComparable)property.GetValue(e)).Equals(filterValue)); + comparison = Expression.Equal(propertyValue, filterValue); break; case FilterOperator.GreaterThan: - result = result.Where(e => ((IComparable)property.GetValue(e)).CompareTo(filterValue) > 0); + comparison = Expression.GreaterThan(propertyValue, filterValue); break; case FilterOperator.LessThan: - result = result.Where(e => ((IComparable)property.GetValue(e)).CompareTo(filterValue) < 0); + comparison = Expression.LessThan(propertyValue, filterValue); break; case FilterOperator.GreaterThanOrEqualTo: - result = result.Where(e => ((IComparable)property.GetValue(e)).CompareTo(filterValue) >= 0); + comparison = Expression.GreaterThanOrEqual(propertyValue, filterValue); break; case FilterOperator.LessThanOrEqualTo: - result = result.Where(e => ((IComparable)property.GetValue(e)).CompareTo(filterValue) <= 0); + comparison = Expression.LessThanOrEqual(propertyValue, filterValue); break; case FilterOperator.Contains: - result = result.Where(e => ((string)property.GetValue(e)).Contains((string)filterValue)); + comparison = Expression.Call(propertyValue, + typeof(string).GetMethods() + .First(m => m.Name == "Contains" && m.GetParameters().Length == 1), + filterValue); break; case FilterOperator.StartsWith: - result = result.Where(e => ((string)property.GetValue(e)).StartsWith((string)filterValue)); - break; + comparison = Expression.Call(propertyValue, + typeof(string).GetMethods() + .First(m => m.Name == "StartsWith" && m.GetParameters().Length == 1), + filterValue); break; default: - result = result.Where(e => ((IComparable)property.GetValue(e)).Equals(filterValue)); + comparison = Expression.Equal(propertyValue, filterValue); break; } + + result = result.Where(Expression.Lambda>( + comparison, + parameter)); } else { - var customMethod = _customFilterMethods.GetType() - .GetMethod(filterTerm.Name); - - if (customMethod != null) - { - result = result.Where( - e => (bool)customMethod.Invoke(_customFilterMethods, new object[] { e })); - } - + result = ApplyCustomMethod(result, filterTerm.Name, _customFilterMethods); } } @@ -130,8 +164,11 @@ namespace Sieve.Services public IQueryable ApplyPagination(SieveModel model, IQueryable result) { - result = result.Skip((model.Page - 1) * model.PageSize) - .Take(model.PageSize); + if (model?.Page == null || model?.PageSize == null) + return result; + + result = result.Skip((model.Page.Value - 1) * model.PageSize.Value) + .Take(model.PageSize.Value); return result; } @@ -147,5 +184,21 @@ namespace Sieve.Services return false; }); } + + private IQueryable ApplyCustomMethod(IQueryable result, string name, object parent, + bool includeUseThenBy = false, bool useThenBy = false) + { + var customMethod = parent?.GetType() + .GetMethod(name); + + if (customMethod != null) + { + var parameters = includeUseThenBy ? new object[] { result, useThenBy } : new object[] { result }; + result = customMethod.Invoke(parent, parameters) + as IQueryable; + } + + return result; + } } } diff --git a/Sieve/Sieve.csproj b/Sieve/Sieve.csproj index a9d176b..91df9e4 100644 --- a/Sieve/Sieve.csproj +++ b/Sieve/Sieve.csproj @@ -5,8 +5,6 @@ - - diff --git a/SieveTests/Controllers/TestController.cs b/SieveTests/Controllers/TestController.cs new file mode 100644 index 0000000..798fa5f --- /dev/null +++ b/SieveTests/Controllers/TestController.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Sieve.Models; +using Sieve.Services; +using SieveTests.Entities; + +namespace SieveTests.Controllers +{ + [Route("api/[controller]/[action]")] + public class TestController : Controller + { + private ISieveProcessor _sieveProcessor; + private ApplicationDbContext _dbContext; + + public TestController(ISieveProcessor sieveProcessor, + ApplicationDbContext dbContext) + { + _sieveProcessor = sieveProcessor; + _dbContext = dbContext; + } + + [HttpGet] + public JsonResult GetAllWithSieve(SieveModel sieveModel) + { + var result = _dbContext.Posts.AsNoTracking(); + + result = _sieveProcessor.ApplyAll(sieveModel, result); + + return Json(result.ToList()); + } + + [HttpGet] + public JsonResult Create(int number = 10) + { + for (int i = 0; i < number; i++) + { + _dbContext.Posts.Add(new Post()); + } + + _dbContext.SaveChanges(); + + return Json(_dbContext.Posts.ToList()); + } + + [HttpGet] + public JsonResult GetAll() + { + return Json(_dbContext.Posts.ToList()); + } + } +} diff --git a/SieveTests/Controllers/ValuesController.cs b/SieveTests/Controllers/ValuesController.cs deleted file mode 100644 index 9beb94b..0000000 --- a/SieveTests/Controllers/ValuesController.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; - -namespace SieveTests.Controllers -{ - [Route("api/[controller]")] - public class ValuesController : Controller - { - // GET api/values - [HttpGet] - public IEnumerable Get() - { - return new string[] { "value1", "value2" }; - } - - // GET api/values/5 - [HttpGet("{id}")] - public string Get(int id) - { - return "value"; - } - - // POST api/values - [HttpPost] - public void Post([FromBody]string value) - { - } - - // PUT api/values/5 - [HttpPut("{id}")] - public void Put(int id, [FromBody]string value) - { - } - - // DELETE api/values/5 - [HttpDelete("{id}")] - public void Delete(int id) - { - } - } -} diff --git a/SieveTests/Entities/ApplicationDbContext.cs b/SieveTests/Entities/ApplicationDbContext.cs new file mode 100644 index 0000000..bf592db --- /dev/null +++ b/SieveTests/Entities/ApplicationDbContext.cs @@ -0,0 +1,20 @@ +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace SieveTests.Entities +{ + public class ApplicationDbContext : DbContext + { + public ApplicationDbContext(DbContextOptions options) : base(options) { } + + public DbSet Posts { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + } + } +} diff --git a/SieveTests/Entities/Post.cs b/SieveTests/Entities/Post.cs new file mode 100644 index 0000000..aae37bf --- /dev/null +++ b/SieveTests/Entities/Post.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Sieve.Attributes; + +namespace SieveTests.Entities +{ + public class Post + { + public int Id { get; set; } + + [Sieve(CanFilter = true, CanSort = true)] + public string Title { get; set; } = Guid.NewGuid().ToString().Replace("-", string.Empty).Substring(0, 8); + + [Sieve(CanFilter = true, CanSort = true)] + public int LikeCount { get; set; } = new Random().Next(0, 1000); + + [Sieve(CanFilter = true, CanSort = true)] + public int CommentCount { get; set; } = new Random().Next(0, 1000); + + [Sieve(CanFilter = true, CanSort = true)] + public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow; + } +} diff --git a/SieveTests/Migrations/20180127005347_Init.Designer.cs b/SieveTests/Migrations/20180127005347_Init.Designer.cs new file mode 100644 index 0000000..741e3af --- /dev/null +++ b/SieveTests/Migrations/20180127005347_Init.Designer.cs @@ -0,0 +1,44 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Storage.Internal; +using SieveTests.Entities; +using System; + +namespace SieveTests.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20180127005347_Init")] + partial class Init + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.0.1-rtm-125") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("SieveTests.Entities.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("CommentCount"); + + b.Property("DateCreated"); + + b.Property("LikeCount"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.ToTable("Posts"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/SieveTests/Migrations/20180127005347_Init.cs b/SieveTests/Migrations/20180127005347_Init.cs new file mode 100644 index 0000000..731dd79 --- /dev/null +++ b/SieveTests/Migrations/20180127005347_Init.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using System; +using System.Collections.Generic; + +namespace SieveTests.Migrations +{ + public partial class Init : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Posts", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), + CommentCount = table.Column(nullable: false), + DateCreated = table.Column(nullable: false), + LikeCount = table.Column(nullable: false), + Title = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Posts", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Posts"); + } + } +} diff --git a/SieveTests/Migrations/ApplicationDbContextModelSnapshot.cs b/SieveTests/Migrations/ApplicationDbContextModelSnapshot.cs new file mode 100644 index 0000000..62195f1 --- /dev/null +++ b/SieveTests/Migrations/ApplicationDbContextModelSnapshot.cs @@ -0,0 +1,43 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Storage.Internal; +using SieveTests.Entities; +using System; + +namespace SieveTests.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + partial class ApplicationDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.0.1-rtm-125") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("SieveTests.Entities.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("CommentCount"); + + b.Property("DateCreated"); + + b.Property("LikeCount"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.ToTable("Posts"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/SieveTests/Program.cs b/SieveTests/Program.cs index 7d2a893..8721cf5 100644 --- a/SieveTests/Program.cs +++ b/SieveTests/Program.cs @@ -14,7 +14,9 @@ namespace SieveTests { public static void Main(string[] args) { - BuildWebHost(args).Run(); + var host = BuildWebHost(args); + + host.Run(); } public static IWebHost BuildWebHost(string[] args) => diff --git a/SieveTests/Properties/launchSettings.json b/SieveTests/Properties/launchSettings.json index a748c44..58147da 100644 --- a/SieveTests/Properties/launchSettings.json +++ b/SieveTests/Properties/launchSettings.json @@ -18,12 +18,11 @@ }, "SieveTests": { "commandName": "Project", - "launchBrowser": true, "launchUrl": "api/values", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "applicationUrl": "http://localhost:65137/" + "applicationUrl": "http://localhost:6500/" } } -} +} \ No newline at end of file diff --git a/SieveTests/SieveTests.csproj b/SieveTests/SieveTests.csproj index 2a6a149..848fba4 100644 --- a/SieveTests/SieveTests.csproj +++ b/SieveTests/SieveTests.csproj @@ -4,6 +4,11 @@ netcoreapp2.0 + + + + + @@ -16,4 +21,8 @@ + + + + diff --git a/SieveTests/Startup.cs b/SieveTests/Startup.cs index b0bccb6..fd35978 100644 --- a/SieveTests/Startup.cs +++ b/SieveTests/Startup.cs @@ -4,10 +4,14 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using Sieve.Models; +using Sieve.Services; +using SieveTests.Entities; namespace SieveTests { @@ -24,6 +28,16 @@ namespace SieveTests public void ConfigureServices(IServiceCollection services) { services.AddMvc(); + + services.AddDbContext(options => + options.UseSqlServer(Configuration.GetConnectionString("TestSqlServer"))); + + services.Configure(Configuration.GetSection("SieveConfig")); + + + //services.AddScoped(); + services.AddScoped, SieveProcessor>(); + } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/SieveTests/appsettings.json b/SieveTests/appsettings.json index 26bb0ac..fde4e8b 100644 --- a/SieveTests/appsettings.json +++ b/SieveTests/appsettings.json @@ -1,4 +1,10 @@ { + "ConnectionStrings": { + "TestSqlServer": "Server=(localdb)\\MSSQLLocalDB; Database=SieveTests;" + }, + "SieveConfig": { + + }, "Logging": { "IncludeScopes": false, "Debug": {