Permalink
Browse files

Abandoned Commands in favor of straight services. Why? I was adding l…

…ayers that were going to be heavily repeated where SS Service layer is already very "commandy" in their handlers. I'm going to try this route and see how she plays out.
  • Loading branch information...
grexican committed May 30, 2018
1 parent c379a69 commit 176da9af34b867bbd31ad32de362019002633caf
Showing with 1,100 additions and 523 deletions.
  1. +5 −5 src/IsNsfw.Command.Interface/IsNsfw.Command.Interface.csproj
  2. +0 −26 src/IsNsfw.Command/CreateLinkCommand.cs
  3. +1 −1 src/IsNsfw.Command/Domains/LinkCommandHandlers.cs
  4. +1 −1 src/IsNsfw.Command/IsNsfw.Command.csproj
  5. +11 −0 src/IsNsfw.Model/ICreatedAt.cs
  6. +1 −1 src/IsNsfw.Model/IsNsfw.Model.csproj
  7. +5 −1 src/IsNsfw.Model/Link.cs
  8. +3 −3 src/IsNsfw.Model/LinkEvent.cs
  9. +4 −0 src/IsNsfw.Model/LinkTag.cs
  10. +8 −0 src/IsNsfw.Repository.Interface/ILinkRepository.cs
  11. +2 −0 src/IsNsfw.Repository.Interface/IRepository.cs
  12. +1 −0 src/IsNsfw.Repository.Interface/ITagRepository.cs
  13. +6 −1 src/IsNsfw.Repository.Interface/IsNsfw.Repository.Interface.csproj
  14. +1 −1 src/IsNsfw.Repository/IsNsfw.Repository.csproj
  15. +55 −0 src/IsNsfw.Repository/LinkRepository.cs
  16. +43 −4 src/IsNsfw.Repository/RepositoryBase.cs
  17. +6 −0 src/IsNsfw.Repository/TagRepository.cs
  18. +29 −0 src/IsNsfw.Service/AppHost.cs
  19. +17 −0 src/IsNsfw.Service/IsNsfw.Service.csproj
  20. +0 −21 src/IsNsfw.ServiceInterface/AppHost.cs
  21. +2 −0 src/IsNsfw.ServiceInterface/IsNsfw.ServiceInterface.csproj
  22. +99 −0 src/IsNsfw.ServiceInterface/LinkService.cs
  23. +53 −0 src/IsNsfw.ServiceInterface/ServiceBase.cs
  24. +26 −0 src/IsNsfw.ServiceInterface/SimpleInjectorIocAdapter.cs
  25. +37 −0 src/IsNsfw.ServiceInterface/Validators/LinkValidators.cs
  26. +28 −0 src/IsNsfw.ServiceInterface/Validators/TagValidator.cs
  27. +20 −0 src/IsNsfw.ServiceInterface/Validators/ValidationHelpers.cs
  28. +8 −2 src/IsNsfw.ServiceModel/IsNsfw.ServiceModel.csproj
  29. +22 −0 src/IsNsfw.ServiceModel/LinkRequests.cs
  30. +0 −3 src/IsNsfw.ServiceModel/Types/.gitignore
  31. +26 −0 src/IsNsfw.ServiceModel/Types/LinkResponse.cs
  32. +0 −100 src/IsNsfw.Tests/CreateLinkCommandValidatorTests.cs
  33. +0 −209 src/IsNsfw.Tests/CreateLinkEventCommandTests.cs
  34. +0 −24 src/IsNsfw.Tests/CreateLinkEventCommandValidatorTests.cs
  35. +233 −0 src/IsNsfw.Tests/CreateLinkEventRequestTests.cs
  36. +63 −59 src/IsNsfw.Tests/{CreateLinkCommandTests.cs → CreateLinkRequestTests.cs}
  37. +161 −0 src/IsNsfw.Tests/CreateLinkRequestValidatorTests.cs
  38. +0 −45 src/IsNsfw.Tests/IntegrationTest.cs
  39. +4 −1 src/IsNsfw.Tests/IsNsfw.Tests.csproj
  40. +109 −0 src/IsNsfw.Tests/LinkServiceTests.cs
  41. +9 −15 src/IsNsfw.sln
  42. +1 −0 src/IsNsfw/IsNsfw.csproj
@@ -1,17 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Reference Include="ServiceStack">
<HintPath>..\..\..\..\Users\egassert\.nuget\packages\servicestack\5.1.1\lib\netstandard2.0\ServiceStack.dll</HintPath>
</Reference>
<Compile Remove="Domains\**" />
<EmbeddedResource Remove="Domains\**" />
<None Remove="Domains\**" />
</ItemGroup>
<ItemGroup>
<Folder Include="Domains\" />
<PackageReference Include="ServiceStack.Core" Version="5.1.1" />
</ItemGroup>
</Project>
@@ -19,30 +19,4 @@ public class CreateLinkCommand : ICommandWithIntResult
// out parameter
public int Id { get; set; }
}
public class CreateLinkCommandValidator : CommandValidatorBase<CreateLinkCommand>
{
private readonly ILinkRepository _linkRepo;
public CreateLinkCommandValidator(ILinkRepository linkRepo)
{
_linkRepo = linkRepo;
RuleFor(m => m.SessionId).NotEmpty();
RuleFor(m => m.Key).NotEmpty();
RuleFor(m => m.Url).NotEmpty().MustBeAUrl();
}
public override ValidationResult Validate(ValidationContext<CreateLinkCommand> context)
{
var ret = base.Validate(context);
if(ret.IsValid)
{
if(_linkRepo.KeyExists(context.InstanceToValidate.Key))
ret.Errors.Add(new ValidationFailure(nameof(context.InstanceToValidate.Key), $"Key '{context.InstanceToValidate.Key}' already exists."));
}
return ret;
}
}
}
@@ -48,7 +48,7 @@ public void Handle(CreateLinkEventCommand command)
UnitOfWork(db =>
{
var c = command.ConvertTo<LinkEvent>();
c.Timestamp = DateTime.UtcNow;
c.CreatedAt = DateTime.UtcNow;
db.Save(c);
switch(c.LinkEventType)
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace IsNsfw.Model
{
public interface ICreatedAt
{
DateTime CreatedAt { get; set; }
}
}
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
View
@@ -4,11 +4,12 @@
using ServiceStack.Auth;
using ServiceStack.DataAnnotations;
using ServiceStack.Model;
using ServiceStack.OrmLite;
namespace IsNsfw.Model
{
[Alias("Links")]
public class Link : IHasIntId, ISoftDelete
public class Link : IHasIntId, ISoftDelete, ICreatedAt
{
[AutoIncrement]
[PrimaryKey]
@@ -39,6 +40,9 @@ public class Link : IHasIntId, ISoftDelete
[Reference]
public List<LinkTag> LinkTags { get; set; }
[Default(OrmLiteVariables.SystemUtc)] // Populated with UTC Date by RDBMS
public DateTime CreatedAt { get; set; }
//[Ignore]
//public List<Tag> Tags { get; set; }
}
@@ -5,7 +5,7 @@
namespace IsNsfw.Model
{
public class LinkEvent : IHasIntId
public class LinkEvent : IHasIntId, ICreatedAt
{
[AutoIncrement]
[PrimaryKey]
@@ -20,7 +20,7 @@ public class LinkEvent : IHasIntId
[Index]
[References(typeof(Link))]
public int? LinkId { get; set; }
public int LinkId { get; set; }
[Reference]
public User User { get; set; }
@@ -31,6 +31,6 @@ public class LinkEvent : IHasIntId
public LinkEventType LinkEventType { get; set; }
[Default(OrmLiteVariables.SystemUtc)] // Populated with UTC Date by RDBMS
public DateTime Timestamp { get; set; }
public DateTime CreatedAt { get; set; }
}
}
@@ -6,6 +6,10 @@ namespace IsNsfw.Model
[CompositeIndex(nameof(LinkId), nameof(TagId))]
public class LinkTag
{
[PrimaryKey]
[Ignore]
public string Id => $"{this.LinkId}/{this.TagId}";
[References(typeof(Link))]
public int LinkId { get; set; }
@@ -2,12 +2,20 @@
using System.Collections.Generic;
using System.Text;
using IsNsfw.Model;
using IsNsfw.ServiceModel.Types;
namespace IsNsfw.Repository.Interface
{
public interface ILinkRepository : IIntRepository<Link>
{
bool KeyExists(string key);
Link GetByKey(string key);
void SetLinkTags(int linkId, IEnumerable<LinkTag> linkTags);
LinkResponse GetLinkResponse(int linkId);
void CreateLinkEvent(LinkEvent linkEvent);
void IncrementTotalViews(int linkId);
void IncrementClickThroughs(int linkId);
void IncrementPreviews(int linkId);
void IncrementTurnBacks(int linkId);
}
}
@@ -9,6 +9,8 @@ public interface IRepository<T, TIdType> where T : IHasId<TIdType>
{
T GetById(TIdType id);
void DeleteById(TIdType id);
TIdType Create(T item);
void Update(T item);
}
public interface IIntRepository<T> : IRepository<T, int> where T : IHasId<int> { }
@@ -10,5 +10,6 @@ public interface ITagRepository : IIntRepository<Tag>
bool KeyExists(string key);
Tag GetByKey(string key);
List<Tag> GetOrderedTags();
Dictionary<string, Tag> GetTagsDictionary();
}
}
@@ -1,11 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ServiceStack.Interfaces.Core" Version="5.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IsNsfw.Model\IsNsfw.Model.csproj" />
<ProjectReference Include="..\IsNsfw.ServiceModel\IsNsfw.ServiceModel.csproj" />
</ItemGroup>
<ItemGroup>
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IsNsfw.Model;
using IsNsfw.Repository.Interface;
using IsNsfw.ServiceModel.Types;
using ServiceStack;
using ServiceStack.Data;
using ServiceStack.OrmLite;
@@ -23,5 +26,57 @@ public Link GetByKey(string key)
{
return Execute(db => db.Single<Link>(m => m.Key == key));
}
public void SetLinkTags(int linkId, IEnumerable<LinkTag> linkTags)
{
Execute(db =>
{
db.Delete<LinkTag>(m => m.LinkId == linkId);
db.InsertAll(linkTags.Where(m => m.LinkId == linkId));
});
}
public LinkResponse GetLinkResponse(int linkId)
{
return Execute(db =>
{
var query = db.From<Link>()
.LeftJoin<Link, LinkTag>( (l, lt) => l.Id == lt.LinkId)
.LeftJoin<LinkTag, Tag>( (lt, t) => lt.TagId == t.Id)
.Where(l => l.Id == linkId);
var results = db.SelectMulti<Link, Tag>(query);
var link = results[0].Item1.ConvertTo<LinkResponse>();
link.Tags = results.Select(m => m.Item2.Key).ToHashSet();
return link;
});
}
public void CreateLinkEvent(LinkEvent linkEvent)
{
Execute(db => db.Save(linkEvent));
}
public void IncrementTotalViews(int linkId)
{
Execute(db => db.UpdateAdd(() => new Link { TotalViews = 1 }, where: m => m.Id == linkId));
}
public void IncrementClickThroughs(int linkId)
{
Execute(db => db.UpdateAdd(() => new Link { TotalClickThroughs = 1 }, where: m => m.Id == linkId));
}
public void IncrementPreviews(int linkId)
{
Execute(db => db.UpdateAdd(() => new Link { TotalPreviews = 1 }, where: m => m.Id == linkId));
}
public void IncrementTurnBacks(int linkId)
{
Execute(db => db.UpdateAdd(() => new Link { TotalTurnBacks = 1 }, where: m => m.Id == linkId));
}
}
}
@@ -26,7 +26,7 @@ public virtual T GetById(TIndex id)
public virtual void DeleteById(TIndex id)
{
if(typeof(ISoftDelete).IsAssignableFrom(typeof(T)))
if (typeof(ISoftDelete).IsAssignableFrom(typeof(T)))
{
Execute(db => db.Update<T>(new { IsDeleted = true }, where: m => m.Id.Equals(id)));
}
@@ -36,15 +36,41 @@ public virtual void DeleteById(TIndex id)
}
}
public virtual TIndex Create(T item)
{
return Execute(db =>
{
db.Save(item);
return item.Id;
});
}
public virtual void Update(T item)
{
Execute(db =>
{
db.Update(item);
});
}
public void ExecuteTransaction(Action<IDbConnection, IDbTransaction> a)
{
using(var db = _factory.OpenDbConnection())
using(var trans = db.OpenTransaction())
using (var db = _factory.OpenDbConnection())
using (var trans = db.OpenTransaction())
{
a(db, trans);
}
}
public TResult ExecuteTransaction<TResult>(Func<IDbConnection, IDbTransaction, TResult> a)
{
using (var db = _factory.OpenDbConnection())
using (var trans = db.OpenTransaction())
{
return a(db, trans);
}
}
public void UnitOfWork(Action<IDbConnection> a)
{
using (var db = _factory.OpenDbConnection())
@@ -56,9 +82,22 @@ public void UnitOfWork(Action<IDbConnection> a)
}
}
public TResult UnitOfWork<TResult>(Func<IDbConnection, TResult> a)
{
using (var db = _factory.OpenDbConnection())
using (var trans = db.OpenTransaction())
{
var ret = a(db);
trans.Commit();
return ret;
}
}
public virtual void Execute(Action<IDbConnection> a)
{
using(var db = _factory.OpenDbConnection())
using (var db = _factory.OpenDbConnection())
a(db);
}
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IsNsfw.Model;
using IsNsfw.Repository.Interface;
@@ -28,5 +29,10 @@ public List<Tag> GetOrderedTags()
{
return Execute(db => db.Select(db.From<Tag>().Where(m => !m.IsDeleted).OrderBy(m => m.SortOrder).ThenBy(m => m.Key)));
}
public Dictionary<string, Tag> GetTagsDictionary()
{
return GetOrderedTags().ToDictionary(m => m.Key, m => m);
}
}
}
Oops, something went wrong.

0 comments on commit 176da9a

Please sign in to comment.