diff --git a/README.md b/README.md index ebed769..9ca290b 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,20 @@ * EventBus for DDD use cases * EntityFramework * Generic Repository Pattern, DbContext, Multiple DbContext control in one unit of work, TransactionScope support - +* Dapper and EF both can use in one application. +* Dapper and EF have their own repositories. `IDapperRepository`, `IRepository` +* Dapper-EntityFramework works under same transaction and unit of work scope, if any exception appears in domain whole transaction will be rollback, including Dapper's insert/deletes and EF's. +* RabbitMQ support +* HangFire support +* Redis support +* A lot of extensions +* Strictly **SOLID** ## Composition Root ```csharp IRootResolver resolver = IocBuilder.New .UseAutofacContainerBuilder() - .UseStove(starterBootstrapperType: typeof(StoveDemoBootstrapper), autoUnitOfWorkInterceptionEnabled: true) + .UseStove(autoUnitOfWorkInterceptionEnabled: true) .UseStoveEntityFramework() .UseStoveDapper() .UseStoveMapster() @@ -40,6 +47,14 @@ IRootResolver resolver = IocBuilder.New .UseStoveNLog() .UseStoveBackgroundJobs() .UseStoveRedisCaching() + .UseStoveRabbitMQ(configuration => + { + configuration.HostAddress = "rabbitmq://localhost/"; + configuration.Username = "admin"; + configuration.Password = "admin"; + configuration.QueueName = "Default"; + return configuration; + }) .UseStoveHangfire(configuration => { configuration.GlobalConfiguration @@ -50,4 +65,9 @@ IRootResolver resolver = IocBuilder.New .RegisterServices(r => r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly())) .CreateResolver(); +var someDomainService = resolver.Resolve(); +someDomainService.DoSomeStuff(); + ``` + +## It will be documented in detail! diff --git a/Stove.sln b/Stove.sln index cb9a898..d56efe4 100644 --- a/Stove.sln +++ b/Stove.sln @@ -38,6 +38,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Stove.Redis", "src\Stove.Re EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Stove.RabbitMQ", "src\Stove.RabbitMQ\Stove.RabbitMQ.xproj", "{C81A0EB0-6379-46C1-9BC5-A9CBBAC0069B}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Stove.RabbitMQ.Tests", "test\Stove.RabbitMQ.Tests\Stove.RabbitMQ.Tests.xproj", "{F024076F-A7AA-4B54-9F01-D3691A8BC988}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Stove.Mapster.Tests", "test\Stove.Mapster.Tests\Stove.Mapster.Tests.xproj", "{7182FAE3-631D-4485-AF40-69D60A8BD8B7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -96,6 +100,14 @@ Global {C81A0EB0-6379-46C1-9BC5-A9CBBAC0069B}.Debug|Any CPU.Build.0 = Debug|Any CPU {C81A0EB0-6379-46C1-9BC5-A9CBBAC0069B}.Release|Any CPU.ActiveCfg = Release|Any CPU {C81A0EB0-6379-46C1-9BC5-A9CBBAC0069B}.Release|Any CPU.Build.0 = Release|Any CPU + {F024076F-A7AA-4B54-9F01-D3691A8BC988}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F024076F-A7AA-4B54-9F01-D3691A8BC988}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F024076F-A7AA-4B54-9F01-D3691A8BC988}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F024076F-A7AA-4B54-9F01-D3691A8BC988}.Release|Any CPU.Build.0 = Release|Any CPU + {7182FAE3-631D-4485-AF40-69D60A8BD8B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7182FAE3-631D-4485-AF40-69D60A8BD8B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7182FAE3-631D-4485-AF40-69D60A8BD8B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7182FAE3-631D-4485-AF40-69D60A8BD8B7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -114,5 +126,7 @@ Global {0213E41B-70C4-4E53-89ED-70A1753CAF4B} = {23CB5044-8ECE-4DDC-89E0-FC1B8EC9DDDF} {555DA8DA-3F03-4943-B6E3-C3ED8D258969} = {23CB5044-8ECE-4DDC-89E0-FC1B8EC9DDDF} {C81A0EB0-6379-46C1-9BC5-A9CBBAC0069B} = {23CB5044-8ECE-4DDC-89E0-FC1B8EC9DDDF} + {F024076F-A7AA-4B54-9F01-D3691A8BC988} = {4D2BAE52-1E23-4321-BBE6-2BAC28F7B389} + {7182FAE3-631D-4485-AF40-69D60A8BD8B7} = {4D2BAE52-1E23-4321-BBE6-2BAC28F7B389} EndGlobalSection EndGlobal diff --git a/appveyor.yml b/appveyor.yml index 00e0960..996a5b6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,6 @@ version: 1.0.{build} -branches: - only: - - master +pull_requests: + do_not_increment_build_number: true before_build: - cmd: dotnet.exe restore assembly_info: @@ -31,10 +30,16 @@ after_build: test: assemblies: - - test\Stove.EntityFramework.Tests\bin\Debug\net452\win7-x64\Stove.EntityFramework.Tests.dll - - test\Stove.Tests\bin\Debug\net452\win7-x64\Stove.Tests.dll + - test\Stove.EntityFramework.Tests\bin\Debug\net461\win7-x64\Stove.EntityFramework.Tests.dll + - test\Stove.Mapster.Tests\bin\Debug\net461\win7-x64\Stove.Mapster.Tests.dll + - test\Stove.RabbitMQ.Tests\bin\Debug\net461\win7-x64\Stove.RabbitMQ.Tests.dll + - test\Stove.Tests\bin\Debug\net461\win7-x64\Stove.Tests.dll + - test\Stove.Tests.SampleApplication\bin\Debug\net461\win7-x64\Stove.Tests.SampleApplication.dll + deploy: - provider: NuGet + on: + branch: master api_key: secure: liSTqN52OJQy9fZJk6gubSgYBAy4EXcEPCDSCLJ/3T9cZufzpTwvBlGPLX+iP2n9 artifacts: diff --git a/src/Stove.Dapper/Dapper/DapperAutoRepositoryTypes.cs b/src/Stove.Dapper/Dapper/DapperAutoRepositoryTypes.cs index 20dbba0..c9ba50a 100644 --- a/src/Stove.Dapper/Dapper/DapperAutoRepositoryTypes.cs +++ b/src/Stove.Dapper/Dapper/DapperAutoRepositoryTypes.cs @@ -1,6 +1,4 @@ using Stove.Dapper.Dapper.Repositories; -using Stove.Domain.Repositories; -using Stove.EntityFramework.EntityFramework; namespace Stove.Dapper.Dapper { @@ -8,7 +6,7 @@ public static class DapperAutoRepositoryTypes { static DapperAutoRepositoryTypes() { - Default = new AutoRepositoryTypesAttribute( + Default = new DapperAutoRepositoryTypeAttribute( typeof(IDapperRepository<>), typeof(IDapperRepository<,>), typeof(DapperRepositoryBase<,>), @@ -16,6 +14,6 @@ static DapperAutoRepositoryTypes() ); } - public static AutoRepositoryTypesAttribute Default { get; private set; } + public static DapperAutoRepositoryTypeAttribute Default { get; private set; } } } diff --git a/src/Stove.Dapper/Dapper/DapperRepositoryRegistrar.cs b/src/Stove.Dapper/Dapper/DapperRepositoryRegistrar.cs index 50ac4fb..586803a 100644 --- a/src/Stove.Dapper/Dapper/DapperRepositoryRegistrar.cs +++ b/src/Stove.Dapper/Dapper/DapperRepositoryRegistrar.cs @@ -13,7 +13,7 @@ public static class DapperRepositoryRegistrar { public static void RegisterRepositories(Type dbContextType, IIocBuilder builder) { - AutoRepositoryTypesAttribute autoRepositoryAttr = dbContextType.GetSingleAttributeOrNull() ?? + AutoRepositoryTypesAttribute autoRepositoryAttr = dbContextType.GetSingleAttributeOrNull() ?? DapperAutoRepositoryTypes.Default; foreach (EntityTypeInfo entityTypeInfo in DbContextHelper.GetEntityTypeInfos(dbContextType)) diff --git a/src/Stove.Dapper/Dapper/Expressions/DapperExpressionVisitor.cs b/src/Stove.Dapper/Dapper/Expressions/DapperExpressionVisitor.cs index 5033689..e4ab494 100644 --- a/src/Stove.Dapper/Dapper/Expressions/DapperExpressionVisitor.cs +++ b/src/Stove.Dapper/Dapper/Expressions/DapperExpressionVisitor.cs @@ -193,7 +193,7 @@ protected override Expression VisitMethodCall(MethodCallExpression node) } // this is a PropertyExpression but as it's internal, to use, we cast to the base MemberExpression instead (see http://social.msdn.microsoft.com/Forums/en-US/ab528f6a-a60e-4af6-bf31-d58e3f373356/resolving-propertyexpressions-and-fieldexpressions-in-a-custom-linq-provider) - _processedProperty = node.Object; + _processedProperty = node.Object; var me = _processedProperty as MemberExpression; AddField(me, op, arg, _unarySpecified); diff --git a/src/Stove.Dapper/Dapper/Extensions/SortingExtensions.cs b/src/Stove.Dapper/Dapper/Extensions/SortingExtensions.cs new file mode 100644 index 0000000..612063d --- /dev/null +++ b/src/Stove.Dapper/Dapper/Extensions/SortingExtensions.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +using DapperExtensions; + +using JetBrains.Annotations; + +namespace Stove.Dapper.Dapper.Extensions +{ + internal static class SortingExtensions + { + [NotNull] + public static List ToSortable([NotNull] this Expression>[] sortingExpression, bool ascending = true) + { + Check.NotNullOrEmpty(sortingExpression, nameof(sortingExpression)); + + var sortList = new List(); + sortingExpression.ToList().ForEach(sortExpression => + { + MemberInfo sortProperty = ReflectionHelper.GetProperty(sortExpression); + sortList.Add(new Sort { Ascending = ascending, PropertyName = sortProperty.Name }); + }); + + return sortList; + } + } +} diff --git a/src/Stove.Dapper/Dapper/Repositories/DapperRepositoryBaseOfTEntity.cs b/src/Stove.Dapper/Dapper/Repositories/DapperRepositoryBaseOfTEntity.cs index b28b88e..b59acaf 100644 --- a/src/Stove.Dapper/Dapper/Repositories/DapperRepositoryBaseOfTEntity.cs +++ b/src/Stove.Dapper/Dapper/Repositories/DapperRepositoryBaseOfTEntity.cs @@ -1,7 +1,6 @@ using System.Data.Entity; using Stove.Domain.Entities; -using Stove.Domain.Repositories; using Stove.EntityFramework.EntityFramework; namespace Stove.Dapper.Dapper.Repositories diff --git a/src/Stove.Dapper/Dapper/Repositories/DapperRepositoryBaseOfTEntityAndTPrimaryKey.cs b/src/Stove.Dapper/Dapper/Repositories/DapperRepositoryBaseOfTEntityAndTPrimaryKey.cs index 1e107fb..05d1926 100644 --- a/src/Stove.Dapper/Dapper/Repositories/DapperRepositoryBaseOfTEntityAndTPrimaryKey.cs +++ b/src/Stove.Dapper/Dapper/Repositories/DapperRepositoryBaseOfTEntityAndTPrimaryKey.cs @@ -11,8 +11,8 @@ using DapperExtensions; using Stove.Dapper.Dapper.Expressions; +using Stove.Dapper.Dapper.Extensions; using Stove.Domain.Entities; -using Stove.Domain.Repositories; using Stove.Domain.Uow; using Stove.EntityFramework.EntityFramework; @@ -232,5 +232,40 @@ public override Task CountAsync(Expression> predicate) { return Connection.CountAsync(predicate.ToPredicateGroup(), ActiveTransaction); } + + public override IEnumerable GetListPaged(Expression> predicate, int pageNumber, int itemsPerPage, bool ascending = true, params Expression>[] sortingExpression) + { + return Connection.GetPage(predicate.ToPredicateGroup(), sortingExpression.ToSortable(ascending), pageNumber, itemsPerPage, ActiveTransaction); + } + + public override IEnumerable GetSet(Expression> predicate, int firstResult, int maxResults, bool ascending = true, params Expression>[] sortingExpression) + { + return Connection.GetSet(predicate.ToPredicateGroup(), sortingExpression.ToSortable(ascending), firstResult, maxResults, ActiveTransaction); + } + + public override void Insert(TEntity entity) + { + Connection.Insert(entity, ActiveTransaction); + } + + public override void Update(TEntity entity) + { + Connection.Update(entity, ActiveTransaction); + } + + public override void Delete(TEntity entity) + { + Connection.Delete(entity, ActiveTransaction); + } + + public override void Delete(Expression> predicate) + { + Connection.Delete(predicate.ToPredicateGroup(), ActiveTransaction); + } + + public override TPrimaryKey InsertAndGetId(TEntity entity) + { + return Connection.Insert(entity, ActiveTransaction); + } } } diff --git a/src/Stove/Domain/Repositories/IDapperRepositoryOfTEntity.cs b/src/Stove.Dapper/Dapper/Repositories/IDapperRepositoryOfTEntity.cs similarity index 79% rename from src/Stove/Domain/Repositories/IDapperRepositoryOfTEntity.cs rename to src/Stove.Dapper/Dapper/Repositories/IDapperRepositoryOfTEntity.cs index c6aecdc..eb650de 100644 --- a/src/Stove/Domain/Repositories/IDapperRepositoryOfTEntity.cs +++ b/src/Stove.Dapper/Dapper/Repositories/IDapperRepositoryOfTEntity.cs @@ -1,6 +1,6 @@ using Stove.Domain.Entities; -namespace Stove.Domain.Repositories +namespace Stove.Dapper.Dapper.Repositories { public interface IDapperRepository : IDapperRepository where TEntity : class, IEntity { diff --git a/src/Stove.Dapper/Dapper/Repositories/IDapperRepositoryOfTEntityAndTPrimaryKey.cs b/src/Stove.Dapper/Dapper/Repositories/IDapperRepositoryOfTEntityAndTPrimaryKey.cs new file mode 100644 index 0000000..50b49dd --- /dev/null +++ b/src/Stove.Dapper/Dapper/Repositories/IDapperRepositoryOfTEntityAndTPrimaryKey.cs @@ -0,0 +1,379 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Threading.Tasks; + +using JetBrains.Annotations; + +using Stove.Domain.Entities; +using Stove.Domain.Repositories; + +namespace Stove.Dapper.Dapper.Repositories +{ + /// + /// Dapper repository abstraction interface. + /// + /// The type of the entity. + /// The type of the primary key. + /// + public interface IDapperRepository : IRepository where TEntity : class, IEntity + { + /// + /// Gets the specified identifier. + /// + /// The identifier. + /// + [CanBeNull] + TEntity Get([NotNull] TPrimaryKey id); + + /// + /// Gets the asynchronous. + /// + /// The identifier. + /// + [CanBeNull] + Task GetAsync([NotNull] TPrimaryKey id); + + /// + /// Gets the list. + /// + /// + [CanBeNull] + IEnumerable GetList(); + + /// + /// Gets the list asynchronous. + /// + /// + [CanBeNull] + Task> GetListAsync(); + + /// + /// Gets the list. + /// + /// The predicate. + /// + [CanBeNull] + IEnumerable GetList([CanBeNull] object predicate); + + /// + /// Gets the list. + /// + /// The predicate. + /// + [CanBeNull] + IEnumerable GetList([CanBeNull] Expression> predicate); + + /// + /// Gets the list asynchronous. + /// + /// The predicate. + /// + [CanBeNull] + Task> GetListAsync([NotNull] object predicate); + + /// + /// Gets the list asynchronous. + /// + /// The predicate. + /// + [CanBeNull] + Task> GetListAsync([NotNull] Expression> predicate); + + /// + /// Gets the list paged asynchronous. + /// + /// The predicate. + /// The page number. + /// The items per page. + /// The sorting property. + /// if set to true [ascending]. + /// + [CanBeNull] + Task> GetListPagedAsync([NotNull] object predicate, int pageNumber, int itemsPerPage, [NotNull] string sortingProperty, bool ascending = true); + + /// + /// Gets the list paged asynchronous. + /// + /// The predicate. + /// The page number. + /// The items per page. + /// The sorting property. + /// if set to true [ascending]. + /// + [CanBeNull] + Task> GetListPagedAsync([NotNull] Expression> predicate, int pageNumber, int itemsPerPage, [NotNull] string sortingProperty, bool ascending = true); + + /// + /// Gets the list paged asynchronous. + /// + /// The predicate. + /// The page number. + /// The items per page. + /// The sorting expression. + /// if set to true [ascending]. + /// + [CanBeNull] + Task> GetListPagedAsync([NotNull] Expression> predicate, int pageNumber, int itemsPerPage, bool ascending = true, [NotNull] params Expression>[] sortingExpression); + + /// + /// Gets the list paged. + /// + /// The predicate. + /// The page number. + /// The items per page. + /// The sorting property. + /// if set to true [ascending]. + /// + [CanBeNull] + IEnumerable GetListPaged([NotNull] object predicate, int pageNumber, int itemsPerPage, [NotNull] string sortingProperty, bool ascending = true); + + /// + /// Gets the list paged. + /// + /// The predicate. + /// The page number. + /// The items per page. + /// The sorting property. + /// if set to true [ascending]. + /// + [CanBeNull] + IEnumerable GetListPaged([NotNull] Expression> predicate, int pageNumber, int itemsPerPage, [NotNull] string sortingProperty, bool ascending = true); + + /// + /// Gets the list paged. + /// + /// The predicate. + /// The page number. + /// The items per page. + /// The sorting expression. + /// if set to true [ascending]. + /// + [CanBeNull] + IEnumerable GetListPaged([NotNull] Expression> predicate, int pageNumber, int itemsPerPage, bool ascending = true, [NotNull] params Expression>[] sortingExpression); + + /// + /// Counts the specified predicate. + /// + /// The predicate. + /// + int Count([NotNull] object predicate); + + /// + /// Counts the specified predicate. + /// + /// The predicate. + /// + int Count([NotNull] Expression> predicate); + + /// + /// Counts the asynchronous. + /// + /// The predicate. + /// + [NotNull] + Task CountAsync([NotNull] object predicate); + + /// + /// Counts the asynchronous. + /// + /// The predicate. + /// + [NotNull] + Task CountAsync([NotNull] Expression> predicate); + + /// + /// Queries the specified query. + /// + /// The query. + /// The parameters. + /// + [CanBeNull] + IEnumerable Query([NotNull] string query, [CanBeNull] object parameters); + + /// + /// Queries the specified query. + /// + /// The query. + /// The parameters. + /// + [CanBeNull] + IEnumerable Query([NotNull] string query, [CanBeNull] object parameters) where TAny : class; + + /// + /// Queries the specified query. + /// + /// The query. + /// The parameters. + /// + [CanBeNull] + Task> QueryAsync([NotNull] string query, [CanBeNull] object parameters) where TAny : class; + + /// + /// Queries the specified query. + /// + /// The type of any. + /// The query. + /// + IEnumerable Query([NotNull] string query) where TAny : class; + + /// + /// Queries the specified query. + /// + /// The type of any. + /// The query. + /// + [CanBeNull] + Task> QueryAsync([NotNull] string query) where TAny : class; + + /// + /// Queries the asynchronous. + /// + /// The query. + /// The parameters. + /// + [CanBeNull] + Task> QueryAsync([NotNull] string query, [CanBeNull] object parameters); + + /// + /// Gets the set. + /// + /// The predicate. + /// The first result. + /// The maximum results. + /// + /// + /// + [CanBeNull] + IEnumerable GetSet([NotNull] object predicate, int firstResult, int maxResults, [NotNull] string sortingProperty, bool ascending = true); + + /// + /// Gets the set. + /// + /// The predicate. + /// The first result. + /// The maximum results. + /// The sorting property. + /// if set to true [ascending]. + /// + [CanBeNull] + IEnumerable GetSet([NotNull] Expression> predicate, int firstResult, int maxResults, [NotNull] string sortingProperty, bool ascending = true); + + /// + /// Gets the set. + /// + /// The predicate. + /// The first result. + /// The maximum results. + /// The sorting expression. + /// if set to true [ascending]. + /// + [CanBeNull] + IEnumerable GetSet([NotNull] Expression> predicate, int firstResult, int maxResults, bool ascending = true, [NotNull] params Expression>[] sortingExpression); + + /// + /// Gets the set asynchronous. + /// + /// The predicate. + /// The first result. + /// The maximum results. + /// The sorting property. + /// if set to true [ascending]. + /// + [CanBeNull] + Task> GetSetAsync([NotNull] object predicate, int firstResult, int maxResults, [NotNull] string sortingProperty, bool ascending = true); + + /// + /// Gets the set asynchronous. + /// + /// The predicate. + /// The first result. + /// The maximum results. + /// The sorting property. + /// if set to true [ascending]. + /// + [CanBeNull] + Task> GetSetAsync([NotNull] Expression> predicate, int firstResult, int maxResults, [NotNull] string sortingProperty, bool ascending = true); + + /// + /// Gets the set asynchronous. + /// + /// The predicate. + /// The first result. + /// The maximum results. + /// if set to true [ascending]. + /// The sorting expression. + /// + [CanBeNull] + Task> GetSetAsync([NotNull] Expression> predicate, int firstResult, int maxResults, bool ascending = true, [NotNull] params Expression>[] sortingExpression); + + /// + /// Inserts the specified entity. + /// + /// The entity. + void Insert([NotNull] TEntity entity); + + /// + /// Inserts the and get identifier. + /// + /// The entity. + TPrimaryKey InsertAndGetId([NotNull] TEntity entity); + + /// + /// Inserts the asynchronous. + /// + /// The entity. + /// + [NotNull] + Task InsertAsync([NotNull] TEntity entity); + + /// + /// Inserts the and get identifier asynchronous. + /// + /// The entity. + /// + [NotNull] + Task InsertAndGetIdAsync([NotNull] TEntity entity); + + /// + /// Updates the specified entity. + /// + /// The entity. + void Update([NotNull] TEntity entity); + + /// + /// Updates the asynchronous. + /// + /// The entity. + [NotNull] + Task UpdateAsync([NotNull] TEntity entity); + + /// + /// Deletes the specified entity. + /// + /// The entity. + void Delete([NotNull] TEntity entity); + + /// + /// Deletes the specified entity. + /// + /// The predicate. + void Delete([NotNull] Expression> predicate); + + /// + /// Deletes the specified entity. + /// + /// The entity. + /// + [NotNull] + Task DeleteAsync([NotNull] TEntity entity); + + /// + /// Deletes the asynchronous. + /// + /// The predicate. + /// + [NotNull] + Task DeleteAsync([NotNull] Expression> predicate); + } +} diff --git a/src/Stove/Domain/Repositories/StoveDapperRepositoryBase.cs b/src/Stove.Dapper/Dapper/Repositories/StoveDapperRepositoryBase.cs similarity index 65% rename from src/Stove/Domain/Repositories/StoveDapperRepositoryBase.cs rename to src/Stove.Dapper/Dapper/Repositories/StoveDapperRepositoryBase.cs index 75e6377..cc0eb72 100644 --- a/src/Stove/Domain/Repositories/StoveDapperRepositoryBase.cs +++ b/src/Stove.Dapper/Dapper/Repositories/StoveDapperRepositoryBase.cs @@ -5,7 +5,7 @@ using Stove.Domain.Entities; -namespace Stove.Domain.Repositories +namespace Stove.Dapper.Dapper.Repositories { public abstract class StoveDapperRepositoryBase : IDapperRepository where TEntity : class, IEntity { @@ -99,5 +99,58 @@ public virtual Task> GetSetAsync(Expression> GetListPagedAsync(Expression> predicate, int pageNumber, int itemsPerPage, bool ascending = true, params Expression>[] sortingExpression) + { + return Task.FromResult(GetListPaged(predicate, pageNumber, itemsPerPage, ascending, sortingExpression)); + } + + public abstract IEnumerable GetListPaged(Expression> predicate, int pageNumber, int itemsPerPage, bool ascending = true, params Expression>[] sortingExpression); + + public abstract IEnumerable GetSet(Expression> predicate, int firstResult, int maxResults, bool ascending = true, params Expression>[] sortingExpression); + + public virtual Task> GetSetAsync(Expression> predicate, int firstResult, int maxResults, bool ascending = true, params Expression>[] sortingExpression) + { + return Task.FromResult(GetSet(predicate, firstResult, maxResults, ascending, sortingExpression)); + } + + public abstract void Insert(TEntity entity); + + public virtual Task InsertAsync(TEntity entity) + { + Insert(entity); + return Task.FromResult(0); + } + + public abstract void Update(TEntity entity); + + public virtual Task UpdateAsync(TEntity entity) + { + Update(entity); + return Task.FromResult(0); + } + + public abstract void Delete(TEntity entity); + + public virtual Task DeleteAsync(TEntity entity) + { + Delete(entity); + return Task.FromResult(0); + } + + public abstract void Delete(Expression> predicate); + + public virtual Task DeleteAsync(Expression> predicate) + { + Delete(predicate); + return Task.FromResult(0); + } + + public abstract TPrimaryKey InsertAndGetId(TEntity entity); + + public virtual Task InsertAndGetIdAsync(TEntity entity) + { + return Task.FromResult(InsertAndGetId(entity)); + } } } diff --git a/src/Stove.Dapper/DapperAutoRepositoryTypeAttribute.cs b/src/Stove.Dapper/DapperAutoRepositoryTypeAttribute.cs new file mode 100644 index 0000000..6eeea98 --- /dev/null +++ b/src/Stove.Dapper/DapperAutoRepositoryTypeAttribute.cs @@ -0,0 +1,20 @@ +using System; + +using JetBrains.Annotations; + +using Stove.EntityFramework.EntityFramework; + +namespace Stove.Dapper +{ + public class DapperAutoRepositoryTypeAttribute : AutoRepositoryTypesAttribute + { + public DapperAutoRepositoryTypeAttribute( + [NotNull] Type repositoryInterface, + [NotNull] Type repositoryInterfaceWithPrimaryKey, + [NotNull] Type repositoryImplementation, + [NotNull] Type repositoryImplementationWithPrimaryKey) + : base(repositoryInterface, repositoryInterfaceWithPrimaryKey, repositoryImplementation, repositoryImplementationWithPrimaryKey) + { + } + } +} diff --git a/src/Stove.Dapper/StoveDapperRegistrationExtensions.cs b/src/Stove.Dapper/StoveDapperRegistrationExtensions.cs index 19e8bf8..09b93c4 100644 --- a/src/Stove.Dapper/StoveDapperRegistrationExtensions.cs +++ b/src/Stove.Dapper/StoveDapperRegistrationExtensions.cs @@ -5,6 +5,8 @@ using Autofac.Extras.IocManager; +using JetBrains.Annotations; + using Stove.Dapper.Dapper; using Stove.EntityFramework.EntityFramework; using Stove.Reflection.Extensions; @@ -13,7 +15,14 @@ namespace Stove.Dapper { public static class StoveDapperRegistrationExtensions { - public static IIocBuilder UseStoveDapper(this IIocBuilder builder) + /// + /// Dapper Integration for Stove, registers and arrange all Dapper structure to Ioc Container. + /// It should be called in composition root to use correctly. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveDapper([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly())); diff --git a/src/Stove.Dapper/project.json b/src/Stove.Dapper/project.json index b6e372b..b8f6ed2 100644 --- a/src/Stove.Dapper/project.json +++ b/src/Stove.Dapper/project.json @@ -1,13 +1,13 @@ { - "version": "0.0.9-*", + "version": "0.0.10-*", "dependencies": { "Autofac": "4.3.0", "Dapper": "1.50.2", "DapperExtensions": "1.5.0", "EntityFramework": "6.1.3", - "Stove": "0.0.9", - "Stove.EntityFramework": "0.0.9-*" + "Stove": "0.0.10", + "Stove.EntityFramework": "0.0.10-*" }, "frameworks": { diff --git a/src/Stove.EntityFramework/EntityFramework/Uow/EfUnitOfWork.cs b/src/Stove.EntityFramework/EntityFramework/Uow/EfUnitOfWork.cs index f8ef237..8181cf7 100644 --- a/src/Stove.EntityFramework/EntityFramework/Uow/EfUnitOfWork.cs +++ b/src/Stove.EntityFramework/EntityFramework/Uow/EfUnitOfWork.cs @@ -9,6 +9,8 @@ using Autofac.Extras.IocManager; +using JetBrains.Annotations; + using Stove.Domain.Uow; using Stove.EntityFramework.EntityFramework.Utils; using Stove.Extensions; @@ -46,6 +48,7 @@ public EfUnitOfWork( ActiveDbContexts = new Dictionary(); } + [NotNull] protected IDictionary ActiveDbContexts { get; } protected override void BeginUow() @@ -58,17 +61,18 @@ protected override void BeginUow() public override void SaveChanges() { - ActiveDbContexts.Values.ToList().ForEach(SaveChangesInDbContext); + GetAllActiveDbContexts().ForEach(SaveChangesInDbContext); } public override async Task SaveChangesAsync() { - foreach (DbContext dbContext in ActiveDbContexts.Values) + foreach (DbContext dbContext in GetAllActiveDbContexts()) { await SaveChangesInDbContextAsync(dbContext); } } + [NotNull] public IReadOnlyList GetAllActiveDbContexts() { return ActiveDbContexts.Values.ToImmutableList(); @@ -98,6 +102,7 @@ protected override async Task CompleteUowAsync() DisposeUow(); } + [NotNull] public virtual TDbContext GetOrCreateDbContext() where TDbContext : DbContext { @@ -140,7 +145,7 @@ protected override void DisposeUow() } else { - foreach (DbContext activeDbContext in ActiveDbContexts.Values) + foreach (DbContext activeDbContext in GetAllActiveDbContexts()) { Release(activeDbContext); } @@ -149,22 +154,22 @@ protected override void DisposeUow() ActiveDbContexts.Clear(); } - protected virtual void SaveChangesInDbContext(DbContext dbContext) + protected virtual void SaveChangesInDbContext([NotNull] DbContext dbContext) { dbContext.SaveChanges(); } - protected virtual async Task SaveChangesInDbContextAsync(DbContext dbContext) + protected virtual async Task SaveChangesInDbContextAsync([NotNull] DbContext dbContext) { await dbContext.SaveChangesAsync(); } - protected virtual void Release(DbContext dbContext) + protected virtual void Release([NotNull] DbContext dbContext) { dbContext.Dispose(); } - private static void ObjectContext_ObjectMaterialized(DbContext dbContext, ObjectMaterializedEventArgs e) + private void ObjectContext_ObjectMaterialized([NotNull] DbContext dbContext, ObjectMaterializedEventArgs e) { Type entityType = ObjectContext.GetObjectType(e.Entity.GetType()); diff --git a/src/Stove.EntityFramework/StoveEntityFrameworkRegistrationExtensions.cs b/src/Stove.EntityFramework/StoveEntityFrameworkRegistrationExtensions.cs index fccfcd5..bf561d7 100644 --- a/src/Stove.EntityFramework/StoveEntityFrameworkRegistrationExtensions.cs +++ b/src/Stove.EntityFramework/StoveEntityFrameworkRegistrationExtensions.cs @@ -5,20 +5,27 @@ using Autofac.Extras.IocManager; +using JetBrains.Annotations; + using Stove.Domain.Uow; using Stove.EntityFramework.EntityFramework; using Stove.EntityFramework.EntityFramework.Uow; -using JetBrains.Annotations; using Stove.Reflection.Extensions; namespace Stove.EntityFramework { public static class StoveEntityFrameworkRegistrationExtensions { - public static IIocBuilder UseStoveEntityFramework(this IIocBuilder builder) + /// + /// Uses the stove entity framework. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveEntityFramework([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly())); - builder.RegisterServices(r => r.Register()); + builder.RegisterServices(r => r.Register()); builder.RegisterServices(r => r.RegisterGeneric(typeof(IDbContextProvider<>), typeof(UnitOfWorkDbContextProvider<>))); builder.RegisterServices(r => r.Register(Lifetime.Singleton)); @@ -28,7 +35,14 @@ public static IIocBuilder UseStoveEntityFramework(this IIocBuilder builder) return builder; } - public static IIocBuilder UseRepositoryRegistrarInAssembly(this IIocBuilder builder, [NotNull] Assembly assembly) + /// + /// Uses the repository registrar in assembly. + /// + /// The builder. + /// The assembly. + /// + [NotNull] + public static IIocBuilder UseRepositoryRegistrarInAssembly([NotNull] this IIocBuilder builder, [NotNull] Assembly assembly) { Check.NotNull(assembly, nameof(assembly)); @@ -37,19 +51,37 @@ public static IIocBuilder UseRepositoryRegistrarInAssembly(this IIocBuilder buil return builder; } - public static IIocBuilder UseStoveTypedConnectionStringResolver(this IIocBuilder builder) + /// + /// Uses the stove typed connection string resolver. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveTypedConnectionStringResolver([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.Register()); return builder; } - public static IIocBuilder UseStoveTransactionScopeEfTransactionStrategy(this IIocBuilder builder) + /// + /// Uses the stove transaction scope ef transaction strategy. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveTransactionScopeEfTransactionStrategy([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.Register()); return builder; } - public static IIocBuilder UseStoveDbContextEfTransactionStrategy(this IIocBuilder builder) + /// + /// Uses the stove database context ef transaction strategy. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveDbContextEfTransactionStrategy([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.Register()); return builder; diff --git a/src/Stove.EntityFramework/project.json b/src/Stove.EntityFramework/project.json index c775bdf..78b11e4 100644 --- a/src/Stove.EntityFramework/project.json +++ b/src/Stove.EntityFramework/project.json @@ -1,15 +1,15 @@ { - "version" : "0.0.9-*", + "version" : "0.0.10-*", "dependencies": { - "Stove": "0.0.9", + "Stove": "0.0.10", "EntityFramework": "6.1.3", "EntityFramework.DynamicFilters": "2.6.0", - "FluentAssemblyScanner": "1.0.5", "System.Collections": "4.3.0", "System.Collections.Immutable": "1.3.1", "Autofac": "4.3.0", - "Autofac.Extras.IocManager": "2.0.7" + "Autofac.Extras.IocManager": "2.0.7", + "FluentAssemblyScanner": "1.0.7" }, "frameworks" : { diff --git a/src/Stove.HangFire/StoveHangfireRegistrationExtensions.cs b/src/Stove.HangFire/StoveHangfireRegistrationExtensions.cs index 8f030d1..7b4d2c8 100644 --- a/src/Stove.HangFire/StoveHangfireRegistrationExtensions.cs +++ b/src/Stove.HangFire/StoveHangfireRegistrationExtensions.cs @@ -3,13 +3,22 @@ using Autofac.Extras.IocManager; +using JetBrains.Annotations; + using Stove.Hangfire.Hangfire; namespace Stove.Hangfire { public static class StoveHangfireRegistrationExtensions { - public static IIocBuilder UseStoveHangfire(this IIocBuilder builder, Func configureAction) + /// + /// Uses the stove hangfire. + /// + /// The builder. + /// The configure action. + /// + [NotNull] + public static IIocBuilder UseStoveHangfire([NotNull] this IIocBuilder builder, [NotNull] Func configureAction) { builder.RegisterServices(r => r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly())); builder.RegisterServices(r => r.Register(context => configureAction)); diff --git a/src/Stove.HangFire/project.json b/src/Stove.HangFire/project.json index a9bea48..3b8bb04 100644 --- a/src/Stove.HangFire/project.json +++ b/src/Stove.HangFire/project.json @@ -1,9 +1,8 @@ { - "version": "0.0.9-*", + "version": "0.0.10-*", "dependencies": { - "Stove": "0.0.9", - "FluentAssemblyScanner": "1.0.5", + "Stove": "0.0.10", "Hangfire": "1.6.8", "Hangfire.Core": "1.6.8", "Hangfire.SqlServer": "1.6.8", @@ -12,7 +11,8 @@ "Newtonsoft.Json": "9.0.1", "Owin": "1.0", "Autofac": "4.3.0", - "Autofac.Extras.IocManager": "2.0.7" + "Autofac.Extras.IocManager": "2.0.7", + "FluentAssemblyScanner": "1.0.7" }, "frameworks": { diff --git a/src/Stove.Mapster/Mapster/AutoMapAttribute.cs b/src/Stove.Mapster/Mapster/AutoMapAttribute.cs index c97448f..cab6a2e 100644 --- a/src/Stove.Mapster/Mapster/AutoMapAttribute.cs +++ b/src/Stove.Mapster/Mapster/AutoMapAttribute.cs @@ -18,7 +18,7 @@ public AutoMapAttribute(params Type[] targetTypes) { } - public override void CreateMap(TypeAdapterConfig configuration, Type destination) + public override void CreateMap(TypeAdapterConfig configuration, Type needstoMap) { if (TargetTypes.IsNullOrEmpty()) { @@ -27,8 +27,8 @@ public override void CreateMap(TypeAdapterConfig configuration, Type destination foreach (Type source in TargetTypes) { - MethodInfo mapToDestination = configuration.GetType().GetMethod("NewConfig").MakeGenericMethod(source, destination); - MethodInfo mapToSource = configuration.GetType().GetMethod("NewConfig").MakeGenericMethod(destination, source); + MethodInfo mapToDestination = configuration.GetType().GetMethod("NewConfig").MakeGenericMethod(source, needstoMap); + MethodInfo mapToSource = configuration.GetType().GetMethod("NewConfig").MakeGenericMethod(needstoMap, source); mapToDestination.Invoke(configuration, null); mapToSource.Invoke(configuration, null); } diff --git a/src/Stove.Mapster/Mapster/AutoMapAttributeBase.cs b/src/Stove.Mapster/Mapster/AutoMapAttributeBase.cs index 7e95a8e..fb03352 100644 --- a/src/Stove.Mapster/Mapster/AutoMapAttributeBase.cs +++ b/src/Stove.Mapster/Mapster/AutoMapAttributeBase.cs @@ -1,18 +1,21 @@ using System; +using JetBrains.Annotations; + using Mapster; namespace Stove.Mapster.Mapster { public abstract class AutoMapAttributeBase : Attribute { - protected AutoMapAttributeBase(params Type[] targetTypes) + protected AutoMapAttributeBase([NotNull] params Type[] targetTypes) { TargetTypes = targetTypes; } + [NotNull] public Type[] TargetTypes { get; private set; } - public abstract void CreateMap(TypeAdapterConfig configuration, Type destination); + public abstract void CreateMap([NotNull] TypeAdapterConfig configuration, [NotNull] Type needstoMap); } } diff --git a/src/Stove.Mapster/Mapster/AutoMapToAttribute.cs b/src/Stove.Mapster/Mapster/AutoMapToAttribute.cs index 4591e26..a1456f7 100644 --- a/src/Stove.Mapster/Mapster/AutoMapToAttribute.cs +++ b/src/Stove.Mapster/Mapster/AutoMapToAttribute.cs @@ -18,14 +18,14 @@ public AutoMapToAttribute(params Type[] targetTypes) { } - public override void CreateMap(TypeAdapterConfig configuration, Type destination) + public override void CreateMap(TypeAdapterConfig configuration, Type source) { if (TargetTypes.IsNullOrEmpty()) { return; } - foreach (Type source in TargetTypes) + foreach (Type destination in TargetTypes) { MethodInfo mapperFunc = configuration.GetType().GetMethod("NewConfig").MakeGenericMethod(source, destination); mapperFunc.Invoke(configuration, null); diff --git a/src/Stove.Mapster/Mapster/IStoveMapsterConfiguraiton.cs b/src/Stove.Mapster/Mapster/IStoveMapsterConfiguration.cs similarity index 73% rename from src/Stove.Mapster/Mapster/IStoveMapsterConfiguraiton.cs rename to src/Stove.Mapster/Mapster/IStoveMapsterConfiguration.cs index f820ff6..9f8ac58 100644 --- a/src/Stove.Mapster/Mapster/IStoveMapsterConfiguraiton.cs +++ b/src/Stove.Mapster/Mapster/IStoveMapsterConfiguration.cs @@ -5,10 +5,12 @@ namespace Stove.Mapster.Mapster { - public interface IStoveMapsterConfiguraiton + public interface IStoveMapsterConfiguration { TypeAdapterConfig Configuration { get; } List> Configurators { get; } + + IAdapter Adapter { get; } } } diff --git a/src/Stove.Mapster/Mapster/MapsterConfigurationExtensions.cs b/src/Stove.Mapster/Mapster/MapsterConfigurationExtensions.cs index 94d3258..3c34329 100644 --- a/src/Stove.Mapster/Mapster/MapsterConfigurationExtensions.cs +++ b/src/Stove.Mapster/Mapster/MapsterConfigurationExtensions.cs @@ -1,13 +1,15 @@ using System; using System.Reflection; +using JetBrains.Annotations; + using Mapster; namespace Stove.Mapster.Mapster { - internal static class AutoMapperConfigurationExtensions + internal static class MapsterConfigurationExtensions { - public static void CreateAutoAttributeMaps(this TypeAdapterConfig configuration, Type type) + public static void CreateAutoAttributeMaps([NotNull] this TypeAdapterConfig configuration, [NotNull] Type type) { foreach (AutoMapAttributeBase autoMapAttribute in type.GetCustomAttributes()) { diff --git a/src/Stove.Mapster/Mapster/MapsterExtensions.cs b/src/Stove.Mapster/Mapster/MapsterExtensions.cs index 62769f0..4f17cd9 100644 --- a/src/Stove.Mapster/Mapster/MapsterExtensions.cs +++ b/src/Stove.Mapster/Mapster/MapsterExtensions.cs @@ -1,4 +1,6 @@ -using Mapster; +using JetBrains.Annotations; + +using Mapster; namespace Stove.Mapster.Mapster { @@ -11,9 +13,9 @@ public static class MapsterExtensions /// /// Type of the destination object /// Source object - public static TDestination MapTo(this object source) + public static TDestination MapTo([NotNull] this object source) { - return source.Adapt(); + return source.Adapt(TypeAdapterConfig.GlobalSettings); } /// @@ -27,7 +29,7 @@ public static TDestination MapTo(this object source) /// public static TDestination MapTo(this TSource source, TDestination destination) { - return source.Adapt(destination); + return source.Adapt(destination, TypeAdapterConfig.GlobalSettings); } } } diff --git a/src/Stove.Mapster/Mapster/MapsterObjectMapper.cs b/src/Stove.Mapster/Mapster/MapsterObjectMapper.cs index a78b5f7..9906c26 100644 --- a/src/Stove.Mapster/Mapster/MapsterObjectMapper.cs +++ b/src/Stove.Mapster/Mapster/MapsterObjectMapper.cs @@ -6,14 +6,21 @@ namespace Stove.Mapster.Mapster { public class MapsterObjectMapper : IObjectMapper { + private readonly IStoveMapsterConfiguration _mapsterConfiguration; + + public MapsterObjectMapper(IStoveMapsterConfiguration mapsterConfiguration) + { + this._mapsterConfiguration = mapsterConfiguration; + } + public TDestination Map(object source) { - return source.Adapt(); + return source.Adapt(_mapsterConfiguration.Configuration); } public TDestination Map(TSource source, TDestination destination) { - return source.Adapt(destination); + return source.Adapt(destination, _mapsterConfiguration.Configuration); } } } diff --git a/src/Stove.Mapster/Mapster/StoveMapsterConfiguration.cs b/src/Stove.Mapster/Mapster/StoveMapsterConfiguration.cs index f4d6eea..b237515 100644 --- a/src/Stove.Mapster/Mapster/StoveMapsterConfiguration.cs +++ b/src/Stove.Mapster/Mapster/StoveMapsterConfiguration.cs @@ -5,16 +5,19 @@ namespace Stove.Mapster.Mapster { - public class StoveMapsterConfiguration : IStoveMapsterConfiguraiton + public class StoveMapsterConfiguration : IStoveMapsterConfiguration { public StoveMapsterConfiguration() { Configurators = new List>(); Configuration = TypeAdapterConfig.GlobalSettings; + Adapter = new Adapter(Configuration); } public TypeAdapterConfig Configuration { get; } public List> Configurators { get; } + + public IAdapter Adapter { get; } } } diff --git a/src/Stove.Mapster/Mapster/StoveMapsterConfigurationExtensions.cs b/src/Stove.Mapster/Mapster/StoveMapsterConfigurationExtensions.cs index 733d1e4..3094dfb 100644 --- a/src/Stove.Mapster/Mapster/StoveMapsterConfigurationExtensions.cs +++ b/src/Stove.Mapster/Mapster/StoveMapsterConfigurationExtensions.cs @@ -1,12 +1,20 @@ -using Stove.Configuration; +using JetBrains.Annotations; + +using Stove.Configuration; namespace Stove.Mapster.Mapster { public static class StoveMapsterConfigurationExtensions { - public static IStoveMapsterConfiguraiton StoveMapster(this IModuleConfigurations configurations) + /// + /// Stove Mapster Configuration + /// + /// The configurations. + /// + [NotNull] + public static IStoveMapsterConfiguration StoveMapster([NotNull] this IModuleConfigurations configurations) { - return configurations.StoveConfiguration.Get(); + return configurations.StoveConfiguration.Get(); } } } diff --git a/src/Stove.Mapster/Properties/AssemblyInfo.cs b/src/Stove.Mapster/Properties/AssemblyInfo.cs index 969b3bd..b57d231 100644 --- a/src/Stove.Mapster/Properties/AssemblyInfo.cs +++ b/src/Stove.Mapster/Properties/AssemblyInfo.cs @@ -5,6 +5,7 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. + [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Stove.Mapster")] @@ -13,7 +14,10 @@ // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. + [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM + [assembly: Guid("0213e41b-70c4-4e53-89ed-70a1753caf4b")] +[assembly: InternalsVisibleTo("Stove.Mapster.Tests")] diff --git a/src/Stove.Mapster/StoveMapsterRegistrationExtensions.cs b/src/Stove.Mapster/StoveMapsterRegistrationExtensions.cs index f579f2b..894ca10 100644 --- a/src/Stove.Mapster/StoveMapsterRegistrationExtensions.cs +++ b/src/Stove.Mapster/StoveMapsterRegistrationExtensions.cs @@ -2,6 +2,8 @@ using Autofac.Extras.IocManager; +using JetBrains.Annotations; + using Stove.Mapster.Mapster; using Stove.ObjectMapping; @@ -9,11 +11,17 @@ namespace Stove.Mapster { public static class StoveMapsterRegistrationExtensions { - public static IIocBuilder UseStoveMapster(this IIocBuilder builder) + /// + /// Uses the stove mapster. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveMapster([NotNull] this IIocBuilder builder) { return builder .RegisterServices(r => r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly())) - .RegisterServices(r => r.Register(Lifetime.Singleton)) + .RegisterServices(r => r.Register(Lifetime.Singleton)) .RegisterServices(r => r.Register(Lifetime.Singleton)); } } diff --git a/src/Stove.Mapster/project.json b/src/Stove.Mapster/project.json index f55a679..1d041c3 100644 --- a/src/Stove.Mapster/project.json +++ b/src/Stove.Mapster/project.json @@ -1,9 +1,9 @@ { - "version" : "0.0.9-*", + "version" : "0.0.10-*", "dependencies" : { "Mapster" : "2.6.1", - "Stove" : "0.0.9" + "Stove" : "0.0.10" }, "frameworks" : { diff --git a/src/Stove.NLog/StoveNLogRegistrationExtensions.cs b/src/Stove.NLog/StoveNLogRegistrationExtensions.cs index 98f9ad7..ab1bad1 100644 --- a/src/Stove.NLog/StoveNLogRegistrationExtensions.cs +++ b/src/Stove.NLog/StoveNLogRegistrationExtensions.cs @@ -3,6 +3,8 @@ using Autofac; using Autofac.Extras.IocManager; +using JetBrains.Annotations; + using NLog; using ILogger = Stove.Log.ILogger; @@ -11,7 +13,13 @@ namespace Stove.NLog { public static class StoveNLogRegistrationExtensions { - public static IIocBuilder UseStoveNLog(this IIocBuilder builder) + /// + /// Uses the stove n log. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveNLog([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly())); builder.RegisterServices(r => r.Register(context => new LoggerAdapter(LogManager.GetCurrentClassLogger()), Lifetime.Singleton)); diff --git a/src/Stove.NLog/project.json b/src/Stove.NLog/project.json index 8a29535..a8927fc 100644 --- a/src/Stove.NLog/project.json +++ b/src/Stove.NLog/project.json @@ -1,10 +1,10 @@ { - "version" : "0.0.9-*", + "version" : "0.0.10-*", "dependencies": { "Autofac": "4.3.0", - "NLog": "4.4.2", - "Stove": "0.0.9" + "NLog": "4.4.3", + "Stove": "0.0.10" }, "frameworks" : { diff --git a/src/Stove.RabbitMQ/RabbitMQ/RabbitMQMessageBus.cs b/src/Stove.RabbitMQ/RabbitMQ/RabbitMQMessageBus.cs index 0709ef1..cf4434b 100644 --- a/src/Stove.RabbitMQ/RabbitMQ/RabbitMQMessageBus.cs +++ b/src/Stove.RabbitMQ/RabbitMQ/RabbitMQMessageBus.cs @@ -1,5 +1,7 @@ using System; +using JetBrains.Annotations; + using MassTransit; using Stove.MQ; @@ -8,9 +10,10 @@ namespace Stove.RabbitMQ.RabbitMQ { public class RabbitMQMessageBus : IMessageBus { + [NotNull] private readonly IBus _bus; - public RabbitMQMessageBus(IBus bus) + public RabbitMQMessageBus([NotNull] IBus bus) { _bus = bus; } diff --git a/src/Stove.RabbitMQ/RabbitMQ/StoveRabbitMQConfigurationExtensions.cs b/src/Stove.RabbitMQ/RabbitMQ/StoveRabbitMQConfigurationExtensions.cs index 23e9ea5..835bbad 100644 --- a/src/Stove.RabbitMQ/RabbitMQ/StoveRabbitMQConfigurationExtensions.cs +++ b/src/Stove.RabbitMQ/RabbitMQ/StoveRabbitMQConfigurationExtensions.cs @@ -1,4 +1,6 @@ -using Stove.Configuration; +using JetBrains.Annotations; + +using Stove.Configuration; namespace Stove.RabbitMQ.RabbitMQ { @@ -9,7 +11,8 @@ public static class StoveRabbitMQConfigurationExtensions /// /// The configurations. /// - public static IStoveRabbitMQConfiguration StoveRabbitMQ(this IModuleConfigurations configurations) + [NotNull] + public static IStoveRabbitMQConfiguration StoveRabbitMQ([NotNull] this IModuleConfigurations configurations) { return configurations.StoveConfiguration.Get(); } diff --git a/src/Stove.RabbitMQ/StoveRabbitMQRegistrationExtensions.cs b/src/Stove.RabbitMQ/StoveRabbitMQRegistrationExtensions.cs index 7da5502..0da0994 100644 --- a/src/Stove.RabbitMQ/StoveRabbitMQRegistrationExtensions.cs +++ b/src/Stove.RabbitMQ/StoveRabbitMQRegistrationExtensions.cs @@ -1,12 +1,13 @@ using System; using System.Reflection; -using System.Transactions; using Autofac; using Autofac.Extras.IocManager; using GreenPipes; +using JetBrains.Annotations; + using MassTransit; using MassTransit.RabbitMqTransport; @@ -17,7 +18,14 @@ namespace Stove.RabbitMQ { public static class StoveRabbitMQRegistrationExtensions { - public static IIocBuilder UseStoveRabbitMQ(this IIocBuilder builder, Func rabbitMQConfigurer = null) + /// + /// Uses the stove rabbit mq. + /// + /// The builder. + /// The rabbit mq configurer. + /// + [NotNull] + public static IIocBuilder UseStoveRabbitMQ([NotNull] this IIocBuilder builder, [CanBeNull] Func rabbitMQConfigurer = null) { builder .RegisterServices(r => @@ -48,10 +56,7 @@ public static IIocBuilder UseStoveRabbitMQ(this IIocBuilder builder, Func - { - rtryConf.Immediate(configuration.MaxRetryCount); - }); + cfg.UseRetry(rtryConf => { rtryConf.Immediate(configuration.MaxRetryCount); }); } cfg.ReceiveEndpoint(host, configuration.QueueName, ec => { ec.LoadFrom(ctx); }); diff --git a/src/Stove.RabbitMQ/project.json b/src/Stove.RabbitMQ/project.json index 422fdef..854ca57 100644 --- a/src/Stove.RabbitMQ/project.json +++ b/src/Stove.RabbitMQ/project.json @@ -1,11 +1,11 @@ { - "version": "0.0.9-*", + "version": "0.0.10-*", "dependencies": { "MassTransit": "3.5.5", "MassTransit.Autofac": "3.5.5", "MassTransit.RabbitMQ": "3.5.5", - "Stove": "0.0.9" + "Stove": "0.0.10" }, "frameworks": { diff --git a/src/Stove.Redis/Redis/IRedisCacheSerializer.cs b/src/Stove.Redis/Redis/IRedisCacheSerializer.cs index 2f83f4a..6e19a9c 100644 --- a/src/Stove.Redis/Redis/IRedisCacheSerializer.cs +++ b/src/Stove.Redis/Redis/IRedisCacheSerializer.cs @@ -1,5 +1,7 @@ using System; +using JetBrains.Annotations; + using StackExchange.Redis; namespace Stove.Redis.Redis @@ -17,6 +19,7 @@ public interface IRedisCacheSerializer /// /// Returns a newly constructed object. /// + [NotNull] object Deserialize(RedisValue objbyte); /// @@ -26,7 +29,8 @@ public interface IRedisCacheSerializer /// Type of the object. /// Returns a string representing the object instance that can be placed into the Redis cache. /// - string Serialize(object value, Type type); + [NotNull] + string Serialize([NotNull] object value, [CanBeNull] Type type); /// /// Produce a string representation of the supplied object. @@ -36,6 +40,7 @@ public interface IRedisCacheSerializer /// Returns a string representing the object instance that can be placed into the Redis cache. /// /// - string Serialize(object value); + [NotNull] + string Serialize([NotNull] object value); } } diff --git a/src/Stove.Redis/Redis/IStoveRedisCacheClientProvider.cs b/src/Stove.Redis/Redis/IStoveRedisCacheClientProvider.cs index 4a90110..1a642ce 100644 --- a/src/Stove.Redis/Redis/IStoveRedisCacheClientProvider.cs +++ b/src/Stove.Redis/Redis/IStoveRedisCacheClientProvider.cs @@ -1,4 +1,6 @@ -using StackExchange.Redis; +using JetBrains.Annotations; + +using StackExchange.Redis; using StackExchange.Redis.Extensions.Core; namespace Stove.Redis.Redis @@ -12,6 +14,7 @@ public interface IStoveRedisCacheClientProvider /// Gets the client. /// /// + [NotNull] ICacheClient GetClient(); } } diff --git a/src/Stove.Redis/Redis/IStoveRedisCacheConfiguration.cs b/src/Stove.Redis/Redis/IStoveRedisCacheConfiguration.cs index 923fc02..d6934c2 100644 --- a/src/Stove.Redis/Redis/IStoveRedisCacheConfiguration.cs +++ b/src/Stove.Redis/Redis/IStoveRedisCacheConfiguration.cs @@ -1,12 +1,16 @@ -using StackExchange.Redis; +using JetBrains.Annotations; + +using StackExchange.Redis; using StackExchange.Redis.Extensions.Core.Configuration; namespace Stove.Redis.Redis { public interface IStoveRedisCacheConfiguration { + [CanBeNull] IRedisCachingConfiguration Configuration { get; set; } + [CanBeNull] ConfigurationOptions ConfigurationOptions { get; set; } } } diff --git a/src/Stove.Redis/Redis/RedisCacheConfigurationExtensions.cs b/src/Stove.Redis/Redis/RedisCacheConfigurationExtensions.cs index f31474e..24c97d8 100644 --- a/src/Stove.Redis/Redis/RedisCacheConfigurationExtensions.cs +++ b/src/Stove.Redis/Redis/RedisCacheConfigurationExtensions.cs @@ -1,4 +1,6 @@ -using Stove.Configuration; +using JetBrains.Annotations; + +using Stove.Configuration; using Stove.Runtime.Caching.Configuration; namespace Stove.Redis.Redis @@ -13,7 +15,8 @@ public static class RedisCacheConfigurationExtensions /// /// The configurations. /// - public static IStoveRedisCacheConfiguration StoveRedis(this IModuleConfigurations configurations) + [NotNull] + public static IStoveRedisCacheConfiguration StoveRedis([NotNull] this IModuleConfigurations configurations) { return configurations.StoveConfiguration.Get(); } diff --git a/src/Stove.Redis/Redis/RedisDatabaseExtensions.cs b/src/Stove.Redis/Redis/RedisDatabaseExtensions.cs index 3bacec8..e1003d9 100644 --- a/src/Stove.Redis/Redis/RedisDatabaseExtensions.cs +++ b/src/Stove.Redis/Redis/RedisDatabaseExtensions.cs @@ -1,5 +1,7 @@ using System; +using JetBrains.Annotations; + using StackExchange.Redis; namespace Stove.Redis.Redis @@ -9,12 +11,10 @@ namespace Stove.Redis.Redis /// internal static class RedisDatabaseExtensions { - public static void KeyDeleteWithPrefix(this IDatabase database, string prefix) + public static void KeyDeleteWithPrefix([NotNull] this IDatabase database, [NotNull] string prefix) { - if (database == null) - { - throw new ArgumentException("Database cannot be null", nameof(database)); - } + Check.NotNull(database, nameof(database)); + Check.NotNull(prefix, nameof(prefix)); if (string.IsNullOrWhiteSpace(prefix)) { @@ -28,17 +28,10 @@ public static void KeyDeleteWithPrefix(this IDatabase database, string prefix) end", values: new RedisValue[] { prefix }); } - public static int KeyCount(this IDatabase database, string prefix) + public static int KeyCount([NotNull] this IDatabase database, [NotNull] string prefix) { - if (database == null) - { - throw new ArgumentException("Database cannot be null", nameof(database)); - } - - if (string.IsNullOrWhiteSpace(prefix)) - { - throw new ArgumentException("Prefix cannot be empty", nameof(database)); - } + Check.NotNull(database, nameof(database)); + Check.NotNull(prefix, nameof(prefix)); RedisResult retVal = database.ScriptEvaluate("return table.getn(redis.call('keys', ARGV[1]))", values: new RedisValue[] { prefix }); diff --git a/src/Stove.Redis/Redis/RedisSerializer.cs b/src/Stove.Redis/Redis/RedisSerializer.cs index 3309ddd..4baab30 100644 --- a/src/Stove.Redis/Redis/RedisSerializer.cs +++ b/src/Stove.Redis/Redis/RedisSerializer.cs @@ -3,6 +3,8 @@ using Autofac.Extras.IocManager; +using JetBrains.Annotations; + using StackExchange.Redis.Extensions.Core; namespace Stove.Redis.Redis @@ -11,7 +13,7 @@ public class RedisSerializer : ISerializer, ITransientDependency { private readonly IRedisCacheSerializer _redisCacheSerializer; - public RedisSerializer(IRedisCacheSerializer redisCacheSerializer) + public RedisSerializer([NotNull] IRedisCacheSerializer redisCacheSerializer) { _redisCacheSerializer = redisCacheSerializer; } diff --git a/src/Stove.Redis/Redis/StoveRedisCache.cs b/src/Stove.Redis/Redis/StoveRedisCache.cs index 5b7e3e0..0fb5973 100644 --- a/src/Stove.Redis/Redis/StoveRedisCache.cs +++ b/src/Stove.Redis/Redis/StoveRedisCache.cs @@ -1,6 +1,8 @@ using System; using System.Threading.Tasks; +using JetBrains.Annotations; + using StackExchange.Redis; using StackExchange.Redis.Extensions.Core; @@ -19,7 +21,7 @@ public class StoveRedisCache : CacheBase /// /// Constructor. /// - public StoveRedisCache(string name, IStoveRedisCacheClientProvider redisCacheClientProvider) : base(name) + public StoveRedisCache([NotNull] string name, [NotNull] IStoveRedisCacheClientProvider redisCacheClientProvider) : base(name) { _cacheClient = redisCacheClientProvider.GetClient(); _database = _cacheClient.Database; @@ -41,7 +43,7 @@ public override void Set(string key, object value, TimeSpan? slidingExpireTime = { throw new StoveException("Can not insert null values to the cache!"); } - + _cacheClient.Add(GetLocalizedKey(key), value, absoluteExpireTime ?? slidingExpireTime ?? DefaultAbsoluteExpireTime ?? DefaultSlidingExpireTime); } @@ -65,7 +67,8 @@ public override void Clear() _database.KeyDeleteWithPrefix(GetLocalizedKey("*")); } - protected virtual string GetLocalizedKey(string key) + [NotNull] + protected virtual string GetLocalizedKey([NotNull] string key) { return "n:" + Name + ",c:" + key; } diff --git a/src/Stove.Redis/Redis/StoveRedisCacheClientProvider.cs b/src/Stove.Redis/Redis/StoveRedisCacheClientProvider.cs index de996d7..b5a99f3 100644 --- a/src/Stove.Redis/Redis/StoveRedisCacheClientProvider.cs +++ b/src/Stove.Redis/Redis/StoveRedisCacheClientProvider.cs @@ -2,6 +2,8 @@ using Autofac.Extras.IocManager; +using JetBrains.Annotations; + using StackExchange.Redis; using StackExchange.Redis.Extensions.Core; @@ -19,7 +21,7 @@ public class StoveRedisCacheClientProvider : IStoveRedisCacheClientProvider, ISi /// /// Initializes a new instance of the class. /// - public StoveRedisCacheClientProvider(IStoveRedisCacheConfiguration configuration, RedisSerializer redisSerializer) + public StoveRedisCacheClientProvider([NotNull] IStoveRedisCacheConfiguration configuration, [NotNull] RedisSerializer redisSerializer) { _configuration = configuration; _redisSerializer = redisSerializer; diff --git a/src/Stove.Redis/Redis/StoveRedisCacheManager.cs b/src/Stove.Redis/Redis/StoveRedisCacheManager.cs index 3c559be..7c9ea6c 100644 --- a/src/Stove.Redis/Redis/StoveRedisCacheManager.cs +++ b/src/Stove.Redis/Redis/StoveRedisCacheManager.cs @@ -1,5 +1,7 @@ using Autofac.Extras.IocManager; +using JetBrains.Annotations; + using Stove.Runtime.Caching; using Stove.Runtime.Caching.Configuration; @@ -13,7 +15,7 @@ public class StoveRedisCacheManager : CacheManagerBase /// /// Initializes a new instance of the class. /// - public StoveRedisCacheManager(IScopeResolver scopeResolver, ICachingConfiguration configuration) + public StoveRedisCacheManager([NotNull] IScopeResolver scopeResolver, [NotNull] ICachingConfiguration configuration) : base(scopeResolver.BeginScope(), configuration) { } diff --git a/src/Stove.Redis/Redis/TypelessRedisCacheSerializer.cs b/src/Stove.Redis/Redis/TypelessRedisCacheSerializer.cs new file mode 100644 index 0000000..e243779 --- /dev/null +++ b/src/Stove.Redis/Redis/TypelessRedisCacheSerializer.cs @@ -0,0 +1,55 @@ +using System; + +using JetBrains.Annotations; + +using StackExchange.Redis; + +using Stove.Json; + +namespace Stove.Redis.Redis +{ + /// + /// Typeless implementation uses JSON as the underlying persistence mechanism. + /// + public class TypelessRedisCacheSerializer : IRedisCacheSerializer + { + /// + /// Creates an instance of the object from its serialized string representation. + /// + /// String representation of the object from the Redis server. + /// + /// Returns a newly constructed object. + /// + public object Deserialize(RedisValue objbyte) + { + return JsonSerializationHelper.Deserialize(objbyte); + } + + /// + /// Produce a string representation of the supplied object. + /// + /// Instance to serialize. + /// Type of the object. + /// + /// Returns a string representing the object instance that can be placed into the Redis cache. + /// + /// + public string Serialize(object value, Type type) + { + return JsonSerializationHelper.Serialize(value); + } + + /// + /// Produce a string representation of the supplied object. + /// + /// Instance to serialize. + /// + /// Returns a string representing the object instance that can be placed into the Redis cache. + /// + /// + public string Serialize(object value) + { + return JsonSerializationHelper.Serialize(value); + } + } +} diff --git a/src/Stove.Redis/StoveRedisRegistrationExtensions.cs b/src/Stove.Redis/StoveRedisRegistrationExtensions.cs index 5194f9b..02559d3 100644 --- a/src/Stove.Redis/StoveRedisRegistrationExtensions.cs +++ b/src/Stove.Redis/StoveRedisRegistrationExtensions.cs @@ -3,6 +3,8 @@ using Autofac.Extras.IocManager; +using JetBrains.Annotations; + using Stove.Redis.Redis; using Stove.Runtime.Caching; @@ -10,7 +12,14 @@ namespace Stove.Redis { public static class StoveRedisRegistrationExtensions { - public static IIocBuilder UseStoveRedisCaching(this IIocBuilder builder, Func redisCacheConfigurer = null) + /// + /// Uses the stove redis caching. + /// + /// The builder. + /// The redis cache configurer. + /// + [NotNull] + public static IIocBuilder UseStoveRedisCaching([NotNull] this IIocBuilder builder, [CanBeNull] Func redisCacheConfigurer = null) { builder.RegisterServices(r => r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly())); builder.RegisterServices(r => r.Register(Lifetime.Singleton)); @@ -24,5 +33,17 @@ public static IIocBuilder UseStoveRedisCaching(this IIocBuilder builder, Func + /// Uses the typeless redis cache serializer. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseTypelessRedisCacheSerializer([NotNull] this IIocBuilder builder) + { + builder.RegisterServices(r => { r.Register(); }); + return builder; + } } } diff --git a/src/Stove.Redis/project.json b/src/Stove.Redis/project.json index 2d3b5a1..fbcf4a3 100644 --- a/src/Stove.Redis/project.json +++ b/src/Stove.Redis/project.json @@ -1,10 +1,10 @@ { - "version" : "0.0.9-*", + "version" : "0.0.10-*", "dependencies": { - "StackExchange.Redis": "1.2.0", + "StackExchange.Redis": "1.2.1", "StackExchange.Redis.Extensions.Core": "2.1.0", - "Stove": "0.0.9" + "Stove": "0.0.10" }, "frameworks" : { diff --git a/src/Stove/Application/Services/ApplicationService.cs b/src/Stove/Application/Services/ApplicationService.cs index b01f85e..626d407 100644 --- a/src/Stove/Application/Services/ApplicationService.cs +++ b/src/Stove/Application/Services/ApplicationService.cs @@ -1,4 +1,6 @@ -using Stove.Runtime.Session; +using JetBrains.Annotations; + +using Stove.Runtime.Session; namespace Stove.Application.Services { @@ -23,6 +25,7 @@ protected ApplicationService() /// /// The stove session. /// + [NotNull] public IStoveSession StoveSession { get; set; } } } diff --git a/src/Stove/BackgroundJobs/BackgroundJob.cs b/src/Stove/BackgroundJobs/BackgroundJob.cs index eb37c13..53c27ba 100644 --- a/src/Stove/BackgroundJobs/BackgroundJob.cs +++ b/src/Stove/BackgroundJobs/BackgroundJob.cs @@ -1,4 +1,6 @@ -using Stove.Domain.Uow; +using JetBrains.Annotations; + +using Stove.Domain.Uow; using Stove.Log; namespace Stove.BackgroundJobs @@ -21,6 +23,7 @@ protected BackgroundJob() /// /// Reference to . /// + [NotNull] public IUnitOfWorkManager UnitOfWorkManager { get @@ -38,6 +41,7 @@ public IUnitOfWorkManager UnitOfWorkManager /// /// Gets current unit of work. /// + [CanBeNull] protected IActiveUnitOfWork CurrentUnitOfWork { get { return UnitOfWorkManager.Current; } @@ -46,6 +50,7 @@ protected IActiveUnitOfWork CurrentUnitOfWork /// /// Reference to the logger to write logs. /// + [NotNull] public ILogger Logger { protected get; set; } public abstract void Execute(TArgs args); diff --git a/src/Stove/BackgroundJobs/BackgroundJobManagerExtensions.cs b/src/Stove/BackgroundJobs/BackgroundJobManagerExtensions.cs index 6ff168b..3f6cf2d 100644 --- a/src/Stove/BackgroundJobs/BackgroundJobManagerExtensions.cs +++ b/src/Stove/BackgroundJobs/BackgroundJobManagerExtensions.cs @@ -1,5 +1,7 @@ using System; +using JetBrains.Annotations; + using Stove.Threading; namespace Stove.BackgroundJobs @@ -19,8 +21,8 @@ public static class BackgroundJobManagerExtensions /// Job priority. /// Job delay (wait duration before first try). public static void Enqueue( - this IBackgroundJobManager backgroundJobManager, - TArgs args, + [NotNull] this IBackgroundJobManager backgroundJobManager, + [NotNull] TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null) where TJob : IBackgroundJob diff --git a/src/Stove/BackgroundJobs/IBackgroundJob.cs b/src/Stove/BackgroundJobs/IBackgroundJob.cs index 200028c..48377ea 100644 --- a/src/Stove/BackgroundJobs/IBackgroundJob.cs +++ b/src/Stove/BackgroundJobs/IBackgroundJob.cs @@ -1,4 +1,6 @@ -namespace Stove.BackgroundJobs +using JetBrains.Annotations; + +namespace Stove.BackgroundJobs { /// /// Defines interface of a background job. @@ -9,6 +11,6 @@ public interface IBackgroundJob /// Executes the job with the . /// /// Job arguments. - void Execute(TArgs args); + void Execute([NotNull] TArgs args); } } diff --git a/src/Stove/BackgroundJobs/IBackgroundJobManager.cs b/src/Stove/BackgroundJobs/IBackgroundJobManager.cs index 2f1e368..6196821 100644 --- a/src/Stove/BackgroundJobs/IBackgroundJobManager.cs +++ b/src/Stove/BackgroundJobs/IBackgroundJobManager.cs @@ -1,6 +1,8 @@ using System; using System.Threading.Tasks; +using JetBrains.Annotations; + using Stove.Threading.BackgrodunWorkers; namespace Stove.BackgroundJobs @@ -19,8 +21,9 @@ public interface IBackgroundJobManager : IBackgroundWorker /// Job arguments. /// Job priority. /// Job delay (wait duration before first try). + [NotNull] Task EnqueueAsync( - TArgs args, + [NotNull] TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null) where TJob : IBackgroundJob; diff --git a/src/Stove/Bootstrapping/BootstrapperCollection.cs b/src/Stove/Bootstrapping/BootstrapperCollection.cs index b805139..4f42df2 100644 --- a/src/Stove/Bootstrapping/BootstrapperCollection.cs +++ b/src/Stove/Bootstrapping/BootstrapperCollection.cs @@ -1,20 +1,23 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; + using Stove.Collections.Extensions; namespace Stove.Bootstrapping { public class BootstrapperCollection : List { - public BootstrapperCollection(Type startupBootstrapperType) + public BootstrapperCollection([NotNull] Type startupBootstrapperType) { StartupBootstrapperType = startupBootstrapperType; } + [NotNull] public Type StartupBootstrapperType { get; } - public static void EnsureKernelBootstrapperToBeFirst(List bootstrappers) + public static void EnsureKernelBootstrapperToBeFirst([NotNull] List bootstrappers) { int kernelBootstrapperIndex = bootstrappers.FindIndex(m => m.Type == typeof(StoveKernelBootstrapper)); if (kernelBootstrapperIndex <= 0) diff --git a/src/Stove/Bootstrapping/BootstrapperInfo.cs b/src/Stove/Bootstrapping/BootstrapperInfo.cs index 1c8f00a..ffeeadd 100644 --- a/src/Stove/Bootstrapping/BootstrapperInfo.cs +++ b/src/Stove/Bootstrapping/BootstrapperInfo.cs @@ -8,7 +8,7 @@ namespace Stove.Bootstrapping { public class BootstrapperInfo { - public BootstrapperInfo([NotNull] Type type, StoveBootstrapper instance) + public BootstrapperInfo([NotNull] Type type, [NotNull] StoveBootstrapper instance) { Type = type; Assembly = Type.Assembly; @@ -16,12 +16,16 @@ public BootstrapperInfo([NotNull] Type type, StoveBootstrapper instance) Dependencies = new List(); } + [NotNull] public StoveBootstrapper Instance { get; } + [NotNull] public Type Type { get; } + [NotNull] public List Dependencies { get; } + [NotNull] public Assembly Assembly { get; } } } diff --git a/src/Stove/Bootstrapping/DependsOn.cs b/src/Stove/Bootstrapping/DependsOn.cs index f43e2f0..f8ef517 100644 --- a/src/Stove/Bootstrapping/DependsOn.cs +++ b/src/Stove/Bootstrapping/DependsOn.cs @@ -1,15 +1,18 @@ using System; +using JetBrains.Annotations; + namespace Stove.Bootstrapping { [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class DependsOnAttribute : Attribute { - public DependsOnAttribute(params Type[] dependedBootstrapperTypes) + public DependsOnAttribute([NotNull] params Type[] dependedBootstrapperTypes) { DependedBootstrapperTypes = dependedBootstrapperTypes; } + [NotNull] public Type[] DependedBootstrapperTypes { get; private set; } } } diff --git a/src/Stove/Bootstrapping/IStoveBootstrapperManager.cs b/src/Stove/Bootstrapping/IStoveBootstrapperManager.cs index d93620e..f1eba99 100644 --- a/src/Stove/Bootstrapping/IStoveBootstrapperManager.cs +++ b/src/Stove/Bootstrapping/IStoveBootstrapperManager.cs @@ -1,12 +1,15 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; + namespace Stove.Bootstrapping { public interface IStoveBootstrapperManager { + [NotNull] IReadOnlyList Bootstrappers { get; } - void StartBootstrappers(Type starterBootStrapperType); + void StartBootstrappers([NotNull] Type starterBootStrapperType); } } diff --git a/src/Stove/Bootstrapping/StoveBootstrapper.cs b/src/Stove/Bootstrapping/StoveBootstrapper.cs index 99cd460..4410bd5 100644 --- a/src/Stove/Bootstrapping/StoveBootstrapper.cs +++ b/src/Stove/Bootstrapping/StoveBootstrapper.cs @@ -5,6 +5,8 @@ using Autofac.Extras.IocManager; +using JetBrains.Annotations; + using Stove.Collections.Extensions; using Stove.Configuration; using Stove.Log; @@ -18,10 +20,13 @@ protected StoveBootstrapper() Logger = NullLogger.Instance; } + [NotNull] public IStoveStartupConfiguration Configuration { get; internal set; } + [NotNull] public IResolver Resolver { get; internal set; } + [NotNull] public ILogger Logger { get; internal set; } public virtual void PreStart() @@ -74,7 +79,8 @@ public static List FindDependedBootstrapperTypes(Type bootstrapper) return list; } - public static List FindDependedBootstrapperTypesRecursivelyIncludingGivenBootstrapper(Type bootstrapperType) + [NotNull] + public static List FindDependedBootstrapperTypesRecursivelyIncludingGivenBootstrapper([NotNull] Type bootstrapperType) { var list = new List(); AddBootstrapperAndDependenciesResursively(list, bootstrapperType); @@ -82,7 +88,7 @@ public static List FindDependedBootstrapperTypesRecursivelyIncludingGivenB return list; } - private static void AddBootstrapperAndDependenciesResursively(List bootstrappers, Type bootstrapperType) + private static void AddBootstrapperAndDependenciesResursively([NotNull] List bootstrappers, [NotNull] Type bootstrapperType) { if (!IsStoveBootstrapper(bootstrapperType)) { diff --git a/src/Stove/Bootstrapping/StoveBootstrapperManager.cs b/src/Stove/Bootstrapping/StoveBootstrapperManager.cs index 977b587..bb70a8d 100644 --- a/src/Stove/Bootstrapping/StoveBootstrapperManager.cs +++ b/src/Stove/Bootstrapping/StoveBootstrapperManager.cs @@ -5,6 +5,8 @@ using Autofac.Extras.IocManager; +using JetBrains.Annotations; + using Stove.Configuration; using Stove.Log; @@ -22,6 +24,7 @@ public StoveBootstrapperManager(IResolver resolver) Logger = NullLogger.Instance; } + [NotNull] public ILogger Logger { get; set; } public IReadOnlyList Bootstrappers => _bootstrappers.ToImmutableList(); diff --git a/src/Stove/Bootstrapping/StoveKernelBootstrapper.cs b/src/Stove/Bootstrapping/StoveKernelBootstrapper.cs index a6addae..38ecff0 100644 --- a/src/Stove/Bootstrapping/StoveKernelBootstrapper.cs +++ b/src/Stove/Bootstrapping/StoveKernelBootstrapper.cs @@ -68,7 +68,7 @@ private void ConfigureEventBus() Type[] genericArgs = @interface.GetGenericArguments(); if (genericArgs.Length == 1) { - _eventBus.Register(genericArgs[0], new IocHandlerFactory(Resolver.Resolve(), impl)); + _eventBus.Register(genericArgs[0], new IocHandlerFactory(Resolver.Resolve().BeginScope(), impl)); } } } diff --git a/src/Stove/Check.cs b/src/Stove/Check.cs index 5665059..970ff58 100644 --- a/src/Stove/Check.cs +++ b/src/Stove/Check.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; +using System.Reflection; using JetBrains.Annotations; @@ -17,17 +19,38 @@ public static T NotNull(T value, [InvokerParameterName] [NotNull] string para { if (value == null) { + NotEmpty(parameterName, nameof(parameterName)); + throw new ArgumentNullException(parameterName); } return value; } + [ContractAnnotation("value:null => halt")] + public static T NotNull( + [NoEnumeration] T value, + [InvokerParameterName] [NotNull] string parameterName, + [NotNull] string propertyName) + { + if (ReferenceEquals(value, null)) + { + NotEmpty(parameterName, nameof(parameterName)); + NotEmpty(propertyName, nameof(propertyName)); + + throw new ArgumentException(propertyName + " " + parameterName + " argument property is null!"); + } + + return value; + } + [ContractAnnotation("value:null => halt")] public static string NotNullOrWhiteSpace(string value, [InvokerParameterName] [NotNull] string parameterName) { if (value.IsNullOrWhiteSpace()) { + NotEmpty(parameterName, nameof(parameterName)); + throw new ArgumentException($"{parameterName} can not be null, empty or white space!", parameterName); } @@ -39,10 +62,89 @@ public static ICollection NotNullOrEmpty(ICollection value, [InvokerPar { if (value.IsNullOrEmpty()) { + NotEmpty(parameterName, nameof(parameterName)); + throw new ArgumentException(parameterName + " can not be null or empty!", parameterName); } return value; } + + [ContractAnnotation("value:null => halt")] + public static string NullButNotEmpty(string value, [InvokerParameterName] [NotNull] string parameterName) + { + if (!ReferenceEquals(value, null) && value.Length == 0) + { + NotEmpty(parameterName, nameof(parameterName)); + + throw new ArgumentException(parameterName + "is empty!", parameterName); + } + + return value; + } + + public static IReadOnlyList HasNoNulls(IReadOnlyList value, [InvokerParameterName] [NotNull] string parameterName) + where T : class + { + NotNull(value, parameterName); + + if (value.Any(e => e == null)) + { + NotEmpty(parameterName, nameof(parameterName)); + + throw new ArgumentException(parameterName); + } + + return value; + } + + public static T IsDefined(T value, [InvokerParameterName] [NotNull] string parameterName) + where T : struct + { + if (!Enum.IsDefined(typeof(T), value)) + { + NotEmpty(parameterName, nameof(parameterName)); + + throw new ArgumentException(parameterName + " is an invalid Enum!", parameterName); + } + + return value; + } + + public static Type ValidEntityType(Type value, [InvokerParameterName] [NotNull] string parameterName) + { + if (!value.GetTypeInfo().IsClass) + { + NotEmpty(parameterName, nameof(parameterName)); + + throw new ArgumentException(parameterName + " is an invalid entity type!", parameterName); + } + + return value; + } + + [ContractAnnotation("value:null => halt")] + public static string NotEmpty(string value, [InvokerParameterName] [NotNull] string parameterName) + { + Exception exception = null; + if (ReferenceEquals(value, null)) + { + exception = new ArgumentNullException(parameterName); + } + else if (value.Trim().Length == 0) + { + exception = new ArgumentException(parameterName + " can not be empty!", parameterName); + } + + if (exception != null) + { + NotEmpty(parameterName, nameof(parameterName)); + + // ReSharper disable once UnthrowableException + throw exception; + } + + return value; + } } } diff --git a/src/Stove/Configuration/IModuleConfigurations.cs b/src/Stove/Configuration/IModuleConfigurations.cs index 110a8cd..9e66b9e 100644 --- a/src/Stove/Configuration/IModuleConfigurations.cs +++ b/src/Stove/Configuration/IModuleConfigurations.cs @@ -1,7 +1,10 @@ -namespace Stove.Configuration +using JetBrains.Annotations; + +namespace Stove.Configuration { public interface IModuleConfigurations { + [NotNull] IStoveStartupConfiguration StoveConfiguration { get; } } } diff --git a/src/Stove/Configuration/ModuleConfigurations.cs b/src/Stove/Configuration/ModuleConfigurations.cs index b7afa6c..1d0c3e7 100644 --- a/src/Stove/Configuration/ModuleConfigurations.cs +++ b/src/Stove/Configuration/ModuleConfigurations.cs @@ -1,8 +1,10 @@ -namespace Stove.Configuration +using JetBrains.Annotations; + +namespace Stove.Configuration { public class ModuleConfigurations : IModuleConfigurations { - public ModuleConfigurations(IStoveStartupConfiguration stoveConfiguration) + public ModuleConfigurations([NotNull] IStoveStartupConfiguration stoveConfiguration) { StoveConfiguration = stoveConfiguration; } diff --git a/src/Stove/Dependency/ResolverExtensions.cs b/src/Stove/Dependency/ResolverExtensions.cs index 7a5ec0f..0e936ad 100644 --- a/src/Stove/Dependency/ResolverExtensions.cs +++ b/src/Stove/Dependency/ResolverExtensions.cs @@ -2,11 +2,20 @@ using Autofac.Extras.IocManager; +using JetBrains.Annotations; + namespace Stove.Dependency { public static class ResolverExtensions { - public static bool ResolveIfExists(this IResolver resolver, out T instance) where T : class + /// + /// Resolves if exists. + /// + /// + /// The resolver. + /// The instance. + /// + public static bool ResolveIfExists([NotNull] this IResolver resolver, [CanBeNull] out T instance) where T : class { instance = null; if (resolver.IsRegistered()) @@ -18,7 +27,14 @@ public static bool ResolveIfExists(this IResolver resolver, out T instance) w return false; } - public static bool ResolveIfExists(this IResolver resolver, Type type, out object instance) + /// + /// Resolves if exists. + /// + /// The resolver. + /// The type. + /// The instance. + /// + public static bool ResolveIfExists([NotNull] this IResolver resolver, [NotNull] Type type, [CanBeNull] out object instance) { instance = null; if (resolver.IsRegistered(type)) diff --git a/src/Stove/Domain/Repositories/IDapperRepositoryOfTEntityAndTPrimaryKey.cs b/src/Stove/Domain/Repositories/IDapperRepositoryOfTEntityAndTPrimaryKey.cs deleted file mode 100644 index fcb7887..0000000 --- a/src/Stove/Domain/Repositories/IDapperRepositoryOfTEntityAndTPrimaryKey.cs +++ /dev/null @@ -1,236 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Threading.Tasks; - -using Stove.Domain.Entities; - -namespace Stove.Domain.Repositories -{ - /// - /// Dapper repository abstraction interface. - /// - /// The type of the entity. - /// The type of the primary key. - /// - public interface IDapperRepository : IRepository where TEntity : class, IEntity - { - /// - /// Gets the specified identifier. - /// - /// The identifier. - /// - TEntity Get(TPrimaryKey id); - - /// - /// Gets the asynchronous. - /// - /// The identifier. - /// - Task GetAsync(TPrimaryKey id); - - /// - /// Gets the list. - /// - /// - IEnumerable GetList(); - - /// - /// Gets the list asynchronous. - /// - /// - Task> GetListAsync(); - - /// - /// Gets the list. - /// - /// The predicate. - /// - IEnumerable GetList(object predicate); - - /// - /// Gets the list. - /// - /// The predicate. - /// - IEnumerable GetList(Expression> predicate); - - /// - /// Gets the list asynchronous. - /// - /// The predicate. - /// - Task> GetListAsync(object predicate); - - /// - /// Gets the list asynchronous. - /// - /// The predicate. - /// - Task> GetListAsync(Expression> predicate); - - /// - /// Gets the list paged asynchronous. - /// - /// The predicate. - /// The page number. - /// The items per page. - /// The sorting property. - /// if set to true [ascending]. - /// - Task> GetListPagedAsync(object predicate, int pageNumber, int itemsPerPage, string sortingProperty, bool ascending = true); - - /// - /// Gets the list paged asynchronous. - /// - /// The predicate. - /// The page number. - /// The items per page. - /// The sorting property. - /// if set to true [ascending]. - /// - Task> GetListPagedAsync(Expression> predicate, int pageNumber, int itemsPerPage, string sortingProperty, bool ascending = true); - - /// - /// Gets the list paged. - /// - /// The predicate. - /// The page number. - /// The items per page. - /// The sorting property. - /// if set to true [ascending]. - /// - IEnumerable GetListPaged(object predicate, int pageNumber, int itemsPerPage, string sortingProperty, bool ascending = true); - - /// - /// Gets the list paged. - /// - /// The predicate. - /// The page number. - /// The items per page. - /// The sorting property. - /// if set to true [ascending]. - /// - IEnumerable GetListPaged(Expression> predicate, int pageNumber, int itemsPerPage, string sortingProperty, bool ascending = true); - - /// - /// Counts the specified predicate. - /// - /// The predicate. - /// - int Count(object predicate); - - /// - /// Counts the specified predicate. - /// - /// The predicate. - /// - int Count(Expression> predicate); - - /// - /// Counts the asynchronous. - /// - /// The predicate. - /// - Task CountAsync(object predicate); - - /// - /// Counts the asynchronous. - /// - /// The predicate. - /// - Task CountAsync(Expression> predicate); - - /// - /// Queries the specified query. - /// - /// The query. - /// The parameters. - /// - IEnumerable Query(string query, object parameters); - - /// - /// Queries the specified query. - /// - /// The query. - /// The parameters. - /// - IEnumerable Query(string query, object parameters) where TAny : class; - - /// - /// Queries the specified query. - /// - /// The query. - /// The parameters. - /// - Task> QueryAsync(string query, object parameters) where TAny : class; - - /// - /// Queries the specified query. - /// - /// The type of any. - /// The query. - /// - IEnumerable Query(string query) where TAny : class; - - /// - /// Queries the specified query. - /// - /// The type of any. - /// The query. - /// - Task> QueryAsync(string query) where TAny : class; - - /// - /// Queries the asynchronous. - /// - /// The query. - /// The parameters. - /// - Task> QueryAsync(string query, object parameters); - - /// - /// Gets the set. - /// - /// The predicate. - /// The first result. - /// The maximum results. - /// - /// - /// - IEnumerable GetSet(object predicate, int firstResult, int maxResults, string sortingProperty, bool ascending = true); - - /// - /// Gets the set. - /// - /// The predicate. - /// The first result. - /// The maximum results. - /// The sorting property. - /// if set to true [ascending]. - /// - IEnumerable GetSet(Expression> predicate, int firstResult, int maxResults, string sortingProperty, bool ascending = true); - - /// - /// Gets the set asynchronous. - /// - /// The predicate. - /// The first result. - /// The maximum results. - /// The sorting property. - /// if set to true [ascending]. - /// - Task> GetSetAsync(object predicate, int firstResult, int maxResults, string sortingProperty, bool ascending = true); - - /// - /// Gets the set asynchronous. - /// - /// The predicate. - /// The first result. - /// The maximum results. - /// The sorting property. - /// if set to true [ascending]. - /// - Task> GetSetAsync(Expression> predicate, int firstResult, int maxResults, string sortingProperty, bool ascending = true); - } -} diff --git a/src/Stove/Extensions/ObjectExtensions.cs b/src/Stove/Extensions/ObjectExtensions.cs index 0b08730..5c98a98 100644 --- a/src/Stove/Extensions/ObjectExtensions.cs +++ b/src/Stove/Extensions/ObjectExtensions.cs @@ -1,47 +1,70 @@ using System; +using System.Collections.Generic; using System.Globalization; using System.Linq; +using JetBrains.Annotations; + namespace Stove.Extensions { /// - /// Extension methods for all objects. + /// Extension methods for all objects. /// public static class ObjectExtensions { /// - /// Used to simplify and beautify casting an object to a type. + /// Used to simplify and beautify casting an object to a type. /// /// Type to be casted /// Object to cast /// Casted object - public static T As(this object obj) + [NotNull] + public static T As([NotNull] this object obj) where T : class { return (T)obj; } /// - /// Converts given object to a value type using method. + /// Converts given object to a value type using method. /// /// Object to be converted /// Type of the target object /// Converted object - public static T To(this object obj) + public static T To([NotNull] this object obj) where T : struct { return (T)Convert.ChangeType(obj, typeof(T), CultureInfo.InvariantCulture); } /// - /// Check if an item is in a list. + /// Check if an item is in a list. /// /// Item to check /// List of items /// Type of the items - public static bool IsIn(this T item, params T[] list) + public static bool IsIn(this T item, [NotNull] params T[] list) { return list.Contains(item); } + + /// + /// Fors the each. + /// + /// + /// The items. + /// The action. + public static void ForEach([CanBeNull] this IEnumerable items, [NotNull] Action action) + { + if (items == null) + { + return; + } + + foreach (T obj in items) + { + action(obj); + } + } } } diff --git a/src/Stove/IO/AppDomainExtensions.cs b/src/Stove/IO/AppDomainExtensions.cs index 6fc0a12..514f027 100644 --- a/src/Stove/IO/AppDomainExtensions.cs +++ b/src/Stove/IO/AppDomainExtensions.cs @@ -1,10 +1,13 @@ using System; +using JetBrains.Annotations; + namespace Stove.IO { public static class AppDomainExtensions { - public static string GetActualDomainPath(this AppDomain @this) + [NotNull] + public static string GetActualDomainPath([NotNull] this AppDomain @this) { return @this.RelativeSearchPath ?? @this.BaseDirectory; } diff --git a/src/Stove/Json/JsonSerializeHelper.cs b/src/Stove/Json/JsonSerializeHelper.cs index 8953ede..b89b9ca 100644 --- a/src/Stove/Json/JsonSerializeHelper.cs +++ b/src/Stove/Json/JsonSerializeHelper.cs @@ -1,5 +1,7 @@ using System; +using JetBrains.Annotations; + using Newtonsoft.Json; namespace Stove.Json @@ -15,17 +17,36 @@ public static class JsonSerializationHelper /// Serializes an object with a type information included. /// So, it can be deserialized using method later. /// - public static string SerializeWithType(object obj) + [NotNull] + public static string SerializeWithType([NotNull] object obj) { return SerializeWithType(obj, obj.GetType()); } + /// + /// Serializes the specified object. + /// + /// The object. + /// + [NotNull] + public static string Serialize([NotNull] object obj) + { + Check.NotNull(obj, nameof(obj)); + + string serialized = obj.ToJsonString(); + return serialized; + } + /// /// Serializes an object with a type information included. /// So, it can be deserialized using method later. /// - public static string SerializeWithType(object obj, Type type) + [NotNull] + public static string SerializeWithType([NotNull] object obj, [NotNull] Type type) { + Check.NotNull(obj, nameof(obj)); + Check.NotNull(type, nameof(type)); + string serialized = obj.ToJsonString(); return $"{type.AssemblyQualifiedName}{TypeSeperator}{serialized}"; @@ -34,7 +55,8 @@ public static string SerializeWithType(object obj, Type type) /// /// Deserializes an object serialized with methods. /// - public static T DeserializeWithType(string serializedObj) + [NotNull] + public static T DeserializeWithType([NotNull] string serializedObj) { return (T)DeserializeWithType(serializedObj); } @@ -42,7 +64,8 @@ public static T DeserializeWithType(string serializedObj) /// /// Deserializes an object serialized with methods. /// - public static object DeserializeWithType(string serializedObj) + [NotNull] + public static object DeserializeWithType([NotNull] string serializedObj) { int typeSeperatorIndex = serializedObj.IndexOf(TypeSeperator); Type type = Type.GetType(serializedObj.Substring(0, typeSeperatorIndex)); @@ -53,5 +76,19 @@ public static object DeserializeWithType(string serializedObj) return JsonConvert.DeserializeObject(serialized, type, options); } + + /// + /// Deserializes the specified serialized object. + /// + /// The serialized object. + /// + [NotNull] + public static object Deserialize([NotNull] string serializedObj) + { + var options = new JsonSerializerSettings(); + options.Converters.Insert(0, new StoveDateTimeConverter()); + + return JsonConvert.DeserializeObject(serializedObj, options); + } } } diff --git a/src/Stove/MQ/IMessageBus.cs b/src/Stove/MQ/IMessageBus.cs index a5e3256..14e3b41 100644 --- a/src/Stove/MQ/IMessageBus.cs +++ b/src/Stove/MQ/IMessageBus.cs @@ -1,15 +1,17 @@ using System; +using JetBrains.Annotations; + namespace Stove.MQ { public interface IMessageBus { - void Publish(TMessage message) where TMessage : class; + void Publish([NotNull] TMessage message) where TMessage : class; - void Publish(object message) where TMessage : class; + void Publish([NotNull] object message) where TMessage : class; - void Publish(object message); + void Publish([NotNull] object message); - void Publish(object message, Type messageType); + void Publish([NotNull] object message, [NotNull] Type messageType); } } diff --git a/src/Stove/NameValue.cs b/src/Stove/NameValue.cs index 88eb7e4..55e84b5 100644 --- a/src/Stove/NameValue.cs +++ b/src/Stove/NameValue.cs @@ -1,5 +1,7 @@ using System; +using JetBrains.Annotations; + namespace Stove { /// @@ -18,7 +20,7 @@ public NameValue() /// /// Creates a new . /// - public NameValue(string name, string value) + public NameValue([NotNull] string name, [NotNull] string value) { Name = name; Value = value; @@ -41,7 +43,7 @@ public NameValue() /// /// Creates a new . /// - public NameValue(string name, T value) + public NameValue([NotNull] string name, [NotNull] T value) { Name = name; Value = value; diff --git a/src/Stove/Properties/AssemblyInfo.cs b/src/Stove/Properties/AssemblyInfo.cs index e17eacc..0fb4f24 100644 --- a/src/Stove/Properties/AssemblyInfo.cs +++ b/src/Stove/Properties/AssemblyInfo.cs @@ -40,3 +40,5 @@ [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: InternalsVisibleTo("Stove.EntityFramework")] [assembly: InternalsVisibleTo("Stove.Tests")] +[assembly: InternalsVisibleTo("Stove.RabbitMQ.Tests")] +[assembly: InternalsVisibleTo("Stove.TestBase")] diff --git a/src/Stove/Reflection/Extensions/MemberInfoExtensions.cs b/src/Stove/Reflection/Extensions/MemberInfoExtensions.cs index 4c79e44..4a94eab 100644 --- a/src/Stove/Reflection/Extensions/MemberInfoExtensions.cs +++ b/src/Stove/Reflection/Extensions/MemberInfoExtensions.cs @@ -1,6 +1,8 @@ using System; using System.Reflection; +using JetBrains.Annotations; + namespace Stove.Reflection.Extensions { public static class MemberInfoExtensions @@ -12,6 +14,7 @@ public static class MemberInfoExtensions /// The member that will be checked for the attribute /// Include inherited attributes /// Returns the attribute object if found. Returns null if not found. + [CanBeNull] public static TAttribute GetSingleAttributeOrNull(this MemberInfo memberInfo, bool inherit = true) where TAttribute : Attribute { @@ -29,6 +32,7 @@ public static TAttribute GetSingleAttributeOrNull(this MemberInfo me return default(TAttribute); } + [CanBeNull] public static TAttribute GetSingleAttributeOfTypeOrBaseTypesOrNull(this Type type, bool inherit = true) where TAttribute : Attribute { diff --git a/src/Stove/Reflection/ReflectionHelper.cs b/src/Stove/Reflection/ReflectionHelper.cs index 4621e47..3cc7d68 100644 --- a/src/Stove/Reflection/ReflectionHelper.cs +++ b/src/Stove/Reflection/ReflectionHelper.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Reflection; +using JetBrains.Annotations; + namespace Stove.Reflection { internal static class ReflectionHelper @@ -192,5 +195,35 @@ internal static void SetValueByPath(object obj, Type objectType, string property property = currentType.GetProperty(properties.Last()); property.SetValue(obj, value); } + + /// + /// Gets the property. + /// + /// The lambda. + /// + [CanBeNull] + [MustUseReturnValue] + public static MemberInfo GetProperty([NotNull] this LambdaExpression lambda) + { + Expression expr = lambda; + for (;;) + { + switch (expr.NodeType) + { + case ExpressionType.Lambda: + expr = ((LambdaExpression)expr).Body; + break; + case ExpressionType.Convert: + expr = ((UnaryExpression)expr).Operand; + break; + case ExpressionType.MemberAccess: + var memberExpression = (MemberExpression)expr; + MemberInfo mi = memberExpression.Member; + return mi; + default: + return null; + } + } + } } } diff --git a/src/Stove/StoveCoreRegistrationExtensions.cs b/src/Stove/StoveCoreRegistrationExtensions.cs index 164f225..8588ac8 100644 --- a/src/Stove/StoveCoreRegistrationExtensions.cs +++ b/src/Stove/StoveCoreRegistrationExtensions.cs @@ -5,6 +5,8 @@ using Autofac.Extras.IocManager; using Autofac.Extras.IocManager.DynamicProxy; +using JetBrains.Annotations; + using Stove.BackgroundJobs; using Stove.Bootstrapping; using Stove.Configuration; @@ -25,13 +27,29 @@ namespace Stove { public static class StoveCoreRegistrationExtensions { - public static IIocBuilder UseStove(this IIocBuilder builder, bool autoUnitOfWorkInterceptionEnabled = false) + /// + /// Uses the stove. + /// + /// The type of the starter bootstrapper. + /// The builder. + /// if set to true [automatic unit of work interception enabled]. + /// + [NotNull] + public static IIocBuilder UseStove([NotNull] this IIocBuilder builder, bool autoUnitOfWorkInterceptionEnabled = false) where TStarterBootstrapper : StoveBootstrapper { return UseStove(builder, typeof(TStarterBootstrapper), autoUnitOfWorkInterceptionEnabled); } - public static IIocBuilder UseStove(this IIocBuilder builder, Type starterBootstrapperType, bool autoUnitOfWorkInterceptionEnabled = false) + /// + /// Uses the stove. + /// + /// The builder. + /// Type of the starter bootstrapper. + /// if set to true [automatic unit of work interception enabled]. + /// + [NotNull] + public static IIocBuilder UseStove([NotNull] this IIocBuilder builder, [NotNull] Type starterBootstrapperType, bool autoUnitOfWorkInterceptionEnabled = false) { if (autoUnitOfWorkInterceptionEnabled) { @@ -45,30 +63,54 @@ public static IIocBuilder UseStove(this IIocBuilder builder, Type starterBootstr }; builder.RegisterServices(r => r.Register(ctx => starterBootstrapperConfigurer)); - RegisterDefaults(builder); + RegisterStoveDefaults(builder); return builder; } - public static IIocBuilder UseStoveDefaultConnectionStringResolver(this IIocBuilder builder) + /// + /// Uses the stove default connection string resolver. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveDefaultConnectionStringResolver([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.Register()); return builder; } - public static IIocBuilder UseStoveDefaultEventBus(this IIocBuilder builder) + /// + /// Uses the stove default event bus. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveDefaultEventBus([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.Register(context => EventBus.Default)); return builder; } - public static IIocBuilder UseStoveEventBus(this IIocBuilder builder) + /// + /// Uses the stove event bus. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveEventBus([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.Register()); return builder; } - public static IIocBuilder UseStoveBackgroundJobs(this IIocBuilder builder) + /// + /// Uses the stove background jobs. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveBackgroundJobs([NotNull] this IIocBuilder builder) { Func configurer = configuration => { @@ -80,53 +122,107 @@ public static IIocBuilder UseStoveBackgroundJobs(this IIocBuilder builder) return builder; } - public static IIocBuilder UseStoveNullEventBus(this IIocBuilder builder) + /// + /// Uses the stove null event bus. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveNullEventBus([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.Register(context => NullEventBus.Instance, keepDefault: true)); return builder; } - public static IIocBuilder UseStoveNullObjectMapper(this IIocBuilder builder) + /// + /// Uses the stove null object mapper. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveNullObjectMapper([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.Register(context => NullObjectMapper.Instance, keepDefault: true)); return builder; } - public static IIocBuilder UseStoveNullUnitOfWork(this IIocBuilder builder) + /// + /// Uses the stove null unit of work. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveNullUnitOfWork([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.Register(keepDefault: true)); return builder; } - public static IIocBuilder UseStoveNullUnitOfWorkFilterExecuter(this IIocBuilder builder) + /// + /// Uses the stove null unit of work filter executer. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveNullUnitOfWorkFilterExecuter([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.Register(keepDefault: true)); return builder; } - public static IIocBuilder UseStoveNullEntityChangedEventHelper(this IIocBuilder builder) + /// + /// Uses the stove null entity changed event helper. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveNullEntityChangedEventHelper([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.Register(keepDefault: true)); return builder; } - public static IIocBuilder UseStoveNullAsyncQueryableExecuter(this IIocBuilder builder) + /// + /// Uses the stove null asynchronous queryable executer. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveNullAsyncQueryableExecuter([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.Register(keepDefault: true)); return builder; } - public static IIocBuilder UseStoveNullMessageBus(this IIocBuilder builder) + /// + /// Uses the stove null message bus. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveNullMessageBus([NotNull] this IIocBuilder builder) { return builder.RegisterServices(r => r.Register(ctx => NullMessageBus.Instance, keepDefault: true)); } - public static IIocBuilder UseStoveNullLogger(this IIocBuilder builder) + /// + /// Uses the stove null logger. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveNullLogger([NotNull] this IIocBuilder builder) { return builder.RegisterServices(r => r.Register(keepDefault: true)); } - public static IIocBuilder UseStoveMemoryCaching(this IIocBuilder builder) + /// + /// Uses the stove memory caching. + /// + /// The builder. + /// + [NotNull] + public static IIocBuilder UseStoveMemoryCaching([NotNull] this IIocBuilder builder) { return builder.RegisterServices(r => r.RegisterType(keepDefault: true)); } @@ -135,10 +231,11 @@ public static IIocBuilder UseStoveMemoryCaching(this IIocBuilder builder) /// Uses the Stove with nullables, prefer when you writing unit tests. /// /// The builder. - /// - /// + /// Type of the starter bootstrapper. + /// if set to true [automatic unit of work interception enabled]. /// - public static IIocBuilder UseStoveWithNullables(this IIocBuilder builder, Type starterBootstrapperType, bool autoUnitOfWorkInterceptionEnabled = false) + [NotNull] + public static IIocBuilder UseStoveWithNullables([NotNull] this IIocBuilder builder, [NotNull] Type starterBootstrapperType, bool autoUnitOfWorkInterceptionEnabled = false) { return builder.UseStove(starterBootstrapperType, autoUnitOfWorkInterceptionEnabled) .UseStoveNullLogger() @@ -151,7 +248,7 @@ public static IIocBuilder UseStoveWithNullables(this IIocBuilder builder, Type s .UseStoveNullMessageBus(); } - private static void RegistryOnRegistered(object sender, ComponentRegisteredEventArgs args) + private static void RegistryOnRegistered([CanBeNull] object sender, [NotNull] ComponentRegisteredEventArgs args) { if (UnitOfWorkHelper.IsConventionalUowClass(args.ComponentRegistration.Activator.LimitType) || UnitOfWorkHelper.HasUnitOfWorkAttribute(args.ComponentRegistration.Activator.LimitType)) @@ -160,12 +257,13 @@ private static void RegistryOnRegistered(object sender, ComponentRegisteredEvent } } - private static void UnitOfWorkRegistrar(ComponentRegisteredEventArgs args) + private static void UnitOfWorkRegistrar([NotNull] ComponentRegisteredEventArgs args) { args.ComponentRegistration.InterceptedBy(true); } - private static void RegisterDefaults(IIocBuilder builder) + [NotNull] + private static void RegisterStoveDefaults([NotNull] this IIocBuilder builder) { builder.RegisterServices(r => r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly())) .RegisterServices(r => r.Register(context => SequentialGuidGenerator.Instance, Lifetime.Singleton)) diff --git a/src/Stove/StoveInitializationException.cs b/src/Stove/StoveInitializationException.cs index 6e1a174..15ab06a 100644 --- a/src/Stove/StoveInitializationException.cs +++ b/src/Stove/StoveInitializationException.cs @@ -1,6 +1,8 @@ using System; using System.Runtime.Serialization; +using JetBrains.Annotations; + namespace Stove { /// @@ -19,7 +21,7 @@ public StoveInitializationException() /// /// Constructor for serializing. /// - public StoveInitializationException(SerializationInfo serializationInfo, StreamingContext context) + public StoveInitializationException([NotNull] SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context) { } @@ -28,7 +30,7 @@ public StoveInitializationException(SerializationInfo serializationInfo, Streami /// Constructor. /// /// Exception message - public StoveInitializationException(string message) + public StoveInitializationException([NotNull] string message) : base(message) { } @@ -38,7 +40,7 @@ public StoveInitializationException(string message) /// /// Exception message /// Inner exception - public StoveInitializationException(string message, Exception innerException) + public StoveInitializationException([NotNull] string message, [CanBeNull] Exception innerException) : base(message, innerException) { } diff --git a/src/Stove/project.json b/src/Stove/project.json index 9296519..3cb88e1 100644 --- a/src/Stove/project.json +++ b/src/Stove/project.json @@ -1,11 +1,11 @@ { - "version" : "0.0.9", + "version" : "0.0.10", "dependencies": { "Autofac": "4.3.0", "Autofac.Extras.IocManager.DynamicProxy": "2.0.7", "Castle.Core": "4.0.0", - "FluentAssemblyScanner": "1.0.5", + "FluentAssemblyScanner": "1.0.7", "JetBrains.Annotations": "10.2.1", "Newtonsoft.Json": "9.0.1", "Nito.AsyncEx": "4.0.1", diff --git a/test/Stove.Demo.ConsoleApp/SomeDomainService.cs b/test/Stove.Demo.ConsoleApp/SomeDomainService.cs index 2fff223..e653769 100644 --- a/test/Stove.Demo.ConsoleApp/SomeDomainService.cs +++ b/test/Stove.Demo.ConsoleApp/SomeDomainService.cs @@ -8,6 +8,7 @@ using MassTransit; using Stove.BackgroundJobs; +using Stove.Dapper.Dapper.Repositories; using Stove.Demo.ConsoleApp.BackgroundJobs; using Stove.Demo.ConsoleApp.DbContexes; using Stove.Demo.ConsoleApp.Dto; @@ -113,6 +114,13 @@ public void DoSomeStuff() IEnumerable person2FromDapper = _personDapperRepository.Query("select * from Person with(nolock) where name =@name", new { name = "Oğuzhan" }); + _personDapperRepository.Insert(new Person("oğuzhan2")); + int id = _personDapperRepository.InsertAndGetId(new Person("oğuzhan3")); + Person person3 = _personDapperRepository.Get(id); + person3.Name = "oğuzhan4"; + _personDapperRepository.Update(person3); + _personDapperRepository.Delete(person3); + #endregion Person person2Cache = _cacheManager.GetCache(DemoCacheName.Demo).Get("person", () => _personRepository.FirstOrDefault(x => x.Name == "Oğuzhan")); diff --git a/test/Stove.Demo.ConsoleApp/project.json b/test/Stove.Demo.ConsoleApp/project.json index 50748b6..df622dc 100644 --- a/test/Stove.Demo.ConsoleApp/project.json +++ b/test/Stove.Demo.ConsoleApp/project.json @@ -10,21 +10,21 @@ "Autofac.Extras.IocManager": "2.0.7", "EntityFramework": "6.1.3", "EntityFrameworkProfiler.Appender": "3.0.3105.0", - "FluentAssemblyScanner": "1.0.5", + "FluentAssemblyScanner": "1.0.7", "Hangfire.Core": "1.6.8", "Hangfire.SqlServer": "1.6.8", "LinqKit": "1.1.8", "MassTransit": "3.5.5", "Newtonsoft.Json": "9.0.1", "Owin": "1.0", - "Stove": "0.0.9", - "Stove.Dapper": "0.0.9-*", - "Stove.EntityFramework": "0.0.9-*", - "Stove.HangFire": "0.0.9-*", - "Stove.Mapster": "0.0.9-*", - "Stove.NLog": "0.0.9-*", + "Stove": "0.0.10", + "Stove.Dapper": "0.0.10-*", + "Stove.EntityFramework": "0.0.10-*", + "Stove.HangFire": "0.0.10-*", + "Stove.Mapster": "0.0.10-*", + "Stove.NLog": "0.0.10-*", "Stove.RabbitMQ": "1.0.0-*", - "Stove.Redis": "0.0.9-*" + "Stove.Redis": "0.0.10-*" }, "frameworks": { diff --git a/test/Stove.EntityFramework.Tests/project.json b/test/Stove.EntityFramework.Tests/project.json index afb2c22..c7d7e27 100644 --- a/test/Stove.EntityFramework.Tests/project.json +++ b/test/Stove.EntityFramework.Tests/project.json @@ -4,7 +4,7 @@ "testRunner": "xunit", "dependencies": { "Autofac": "4.3.0", - "Stove.EntityFramework": "0.0.9-*", + "Stove.EntityFramework": "0.0.10-*", "Stove.TestBase": "0.0.1-*" }, diff --git a/test/Stove.Mapster.Tests/AutoMapping_Tests.cs b/test/Stove.Mapster.Tests/AutoMapping_Tests.cs new file mode 100644 index 0000000..55e09a8 --- /dev/null +++ b/test/Stove.Mapster.Tests/AutoMapping_Tests.cs @@ -0,0 +1,362 @@ +using System; + +using JetBrains.Annotations; + +using Mapster; + +using Shouldly; + +using Stove.Configuration; +using Stove.Mapster.Mapster; +using Stove.ObjectMapping; + +using Xunit; + +namespace Stove.Mapster.Tests +{ + public class AutoMapping_Tests : StoveMapsterTestApplication + { + public AutoMapping_Tests() + { + Building(builder => { builder.UseStoveMapster(); }).Ok(); + } + + [Fact] + public void adapter_should_not_be_null() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + IStoveMapsterConfiguration mapsterConfiguration = LocalResolver.Resolve().StoveMapster(); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + IAdapter adapter = mapsterConfiguration.Adapter; + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + adapter.ShouldNotBeNull(); + } + + [Fact] + public void mapping_should_work_with_classic_way_when_only_TDestination_provided() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var mapper = LocalResolver.Resolve(); + + var myclass = new MyClass { TestProperty = "Oguzhan" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + var mappedObject = mapper.Map(myclass); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + mappedObject.TestProperty.ShouldNotBeNull(); + mappedObject.TestProperty.ShouldBe("Oguzhan"); + } + + [Fact] + public void auto_attibute_mapping_should_work_when_only_TDestination_provided() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var mapper = LocalResolver.Resolve(); + + var myclass = new MyClass { TestProperty = "Oguzhan" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + var mappedObject = mapper.Map(myclass); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + mappedObject.TestProperty.ShouldNotBeNull(); + mappedObject.TestProperty.ShouldBe("Oguzhan"); + } + + [Fact] + public void auto_attibute_mapping_should_work_when_only_TDestination_and_TSource_provided() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var mapper = LocalResolver.Resolve(); + + var myclass = new MyClass { TestProperty = "Oguzhan" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + MyClassDto mappedObject = mapper.Map(myclass, new MyClassDto()); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + mappedObject.TestProperty.ShouldNotBeNull(); + mappedObject.TestProperty.ShouldBe("Oguzhan"); + } + + [Fact] + public void auto_attibute_mapping_should_throw_CompileException_when_target_types_are_null_while_using_From_aspect() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var mapper = LocalResolver.Resolve(); + + var myclass = new MyClassTargetTypeNull { TestProperty = "Oguzhan" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action mappingAction = () => { mapper.Map(myclass, new MyClassDto()); }; + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + mappingAction.ShouldThrow(); + } + + [Fact] + public void auto_attibute_mapping_should_throw_CompileException_when_target_types_are_null_while_using_two_way_aspect() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var mapper = LocalResolver.Resolve(); + + var myclass = new MyClassTargetTypeNullTwoWay { TestProperty = "Oguzhan" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action mappingAction = () => { mapper.Map(myclass, new MyClassDto()); }; + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + mappingAction.ShouldThrow(); + } + + [Fact] + public void auto_attribute_type_should_work_with_multiple_attributes_when_TSource_and_TDestination_provided() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var mapper = LocalResolver.Resolve(); + + var myclass = new MyClassWithMultipleAttribute { TestProperty = "Oguzhan" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + MyClassDto mappedObject1 = mapper.Map(myclass, new MyClassDto()); + MyClassDto2 mappedObject2 = mapper.Map(myclass, new MyClassDto2()); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + mappedObject1.ShouldNotBeNull(); + mappedObject2.ShouldNotBeNull(); + mappedObject1.TestProperty.ShouldBe("Oguzhan"); + mappedObject2.TestProperty.ShouldBe("Oguzhan"); + } + + [Fact] + public void auto_attribute_type_should_work_using_two_way_aspect() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var mapper = LocalResolver.Resolve(); + var myclass = new MyClassTwoWay { TestProperty = "Oguzhan" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + MyClassDto mappedObject = mapper.Map(myclass, new MyClassDto()); + MyClassTwoWay twoWayMappedObject = mapper.Map(mappedObject, new MyClassTwoWay()); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + mappedObject.ShouldNotBeNull(); + mappedObject.TestProperty.ShouldBe("Oguzhan"); + twoWayMappedObject.ShouldNotBeNull(); + twoWayMappedObject.TestProperty.ShouldBe("Oguzhan"); + } + + [Fact] + public void auto_attribute_type_should_work_using_two_way_aspect_with_multiple_types() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var mapper = LocalResolver.Resolve(); + var myclass = new MyClassTwoWayMultipleTypes { TestProperty = "Oguzhan" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + MyClassDto mappedObject = mapper.Map(myclass, new MyClassDto()); + MyClassDto2 mappedObject2 = mapper.Map(myclass, new MyClassDto2()); + MyClassTwoWayMultipleTypes twoWayMappedObject = mapper.Map(mappedObject, new MyClassTwoWayMultipleTypes()); + MyClassTwoWayMultipleTypes twoWayMappedObject2 = mapper.Map(mappedObject2, new MyClassTwoWayMultipleTypes()); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + mappedObject.ShouldNotBeNull(); + mappedObject.TestProperty.ShouldBe("Oguzhan"); + twoWayMappedObject.ShouldNotBeNull(); + twoWayMappedObject.TestProperty.ShouldBe("Oguzhan"); + mappedObject2.ShouldNotBeNull(); + mappedObject2.TestProperty.ShouldBe("Oguzhan"); + twoWayMappedObject2.ShouldNotBeNull(); + twoWayMappedObject2.TestProperty.ShouldBe("Oguzhan"); + } + + [Fact] + public void auto_attribute_type_should_work_with_multiple_attributes_using_to_aspect() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var mapper = LocalResolver.Resolve(); + var myclassDto = new MyClassDto { TestProperty = "Oguzhan" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + var mappedObject1 = mapper.Map(myclassDto); + var mappedObject2 = mapper.Map(myclassDto); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + mappedObject1.ShouldNotBeNull(); + mappedObject1.TestProperty.ShouldBe("Oguzhan"); + mappedObject2.ShouldNotBeNull(); + mappedObject2.TestProperty.ShouldBe("Oguzhan"); + } + + [Fact] + public void auto_attribute_type_should_throw_CompileException_with_null_types_using_to_aspect() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var mapper = LocalResolver.Resolve(); + var myclassDto = new MyClassDtoNullTypes { TestProperty = "Oguzhan" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action mappingAction = () => { mapper.Map(myclassDto); }; + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + mappingAction.ShouldThrow(); + } + + [Fact] + public void mapping_should_work_with_extensions() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var myclass = new MyClass { TestProperty = "Oguzhan" }; + var myclassDto = new MyClassDto(); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + var mappedObject = myclass.MapTo(); + var mappedObject2 = myclass.MapTo(myclassDto); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + mappedObject.ShouldNotBeNull(); + mappedObject.TestProperty.ShouldBe("Oguzhan"); + mappedObject2.ShouldNotBeNull(); + mappedObject2.TestProperty.ShouldBe("Oguzhan"); + } + + [UsedImplicitly] + [AutoMapFrom(typeof(MyClassDto))] + public class MyClass + { + public string TestProperty { get; set; } + } + + [AutoMapFrom(typeof(MyClassDto), typeof(MyClassDto2))] + public class MyClassWithMultipleAttribute + { + public string TestProperty { get; set; } + } + + [AutoMap(typeof(MyClassDto))] + public class MyClassTwoWay + { + public string TestProperty { get; set; } + } + + public class MyClassToAspect1 + { + public string TestProperty { get; set; } + } + + public class MyClassToAspect2 + { + public string TestProperty { get; set; } + } + + [AutoMap(typeof(MyClassDto), typeof(MyClassDto2))] + public class MyClassTwoWayMultipleTypes + { + public string TestProperty { get; set; } + } + + [AutoMapFrom(null)] + public class MyClassTargetTypeNull + { + public string TestProperty { get; set; } + } + + [AutoMap(null)] + public class MyClassTargetTypeNullTwoWay + { + public string TestProperty { get; set; } + } + + [AutoMapTo(typeof(MyClassToAspect1), typeof(MyClassToAspect2))] + public class MyClassDto + { + public string TestProperty { get; set; } + } + + [AutoMapTo(null)] + public class MyClassDtoNullTypes + { + public string TestProperty { get; set; } + } + + public class MyClassDto2 + { + public string TestProperty { get; set; } + } + } +} diff --git a/test/Stove.Mapster.Tests/Properties/AssemblyInfo.cs b/test/Stove.Mapster.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..fd4ebea --- /dev/null +++ b/test/Stove.Mapster.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Stove.Mapster.Tests")] +[assembly: AssemblyTrademark("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7182fae3-631d-4485-af40-69d60a8bd8b7")] diff --git a/test/Stove.Mapster.Tests/Stove.Mapster.Tests.xproj b/test/Stove.Mapster.Tests/Stove.Mapster.Tests.xproj new file mode 100644 index 0000000..c33d3f0 --- /dev/null +++ b/test/Stove.Mapster.Tests/Stove.Mapster.Tests.xproj @@ -0,0 +1,21 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + 7182fae3-631d-4485-af40-69d60a8bd8b7 + Stove.Mapster.Tests + .\obj + .\bin\ + v4.6.1 + + + + 2.0 + + + diff --git a/test/Stove.Mapster.Tests/StoveMapsterTestApplication.cs b/test/Stove.Mapster.Tests/StoveMapsterTestApplication.cs new file mode 100644 index 0000000..bd057a4 --- /dev/null +++ b/test/Stove.Mapster.Tests/StoveMapsterTestApplication.cs @@ -0,0 +1,14 @@ +using System.Reflection; + +using Stove.TestBase; + +namespace Stove.Mapster.Tests +{ + public class StoveMapsterTestApplication : ApplicationTestBase + { + public StoveMapsterTestApplication() + { + Building(builder => { builder.RegisterServices(r => r.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly())); }); + } + } +} diff --git a/test/Stove.Mapster.Tests/StoveMapsterTestBootstrapper.cs b/test/Stove.Mapster.Tests/StoveMapsterTestBootstrapper.cs new file mode 100644 index 0000000..8fb7df6 --- /dev/null +++ b/test/Stove.Mapster.Tests/StoveMapsterTestBootstrapper.cs @@ -0,0 +1,19 @@ +using Stove.Bootstrapping; +using Stove.Mapster.Mapster; + +namespace Stove.Mapster.Tests +{ + [DependsOn( + typeof(StoveMapsterBootstrapper) + )] + public class StoveMapsterTestBootstrapper : StoveBootstrapper + { + public override void PreStart() + { + Configuration.Modules.StoveMapster().Configurators.Add(config => + { + config.RequireExplicitMapping = true; + }); + } + } +} diff --git a/test/Stove.Mapster.Tests/project.json b/test/Stove.Mapster.Tests/project.json new file mode 100644 index 0000000..e3a955b --- /dev/null +++ b/test/Stove.Mapster.Tests/project.json @@ -0,0 +1,16 @@ +{ + "version" : "1.0.0-*", + + "testRunner" : "xunit", + + "dependencies" : { + "Stove.Mapster" : "0.0.10-*", + "Stove.TestBase" : "0.0.1-*" + }, + + "frameworks" : { + "net461" : { + + } + } +} diff --git a/test/Stove.RabbitMQ.Tests/Properties/AssemblyInfo.cs b/test/Stove.RabbitMQ.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..7f29126 --- /dev/null +++ b/test/Stove.RabbitMQ.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Stove.RabbitMQ.Tests")] +[assembly: AssemblyTrademark("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f024076f-a7aa-4b54-9f01-d3691a8bc988")] diff --git a/test/Stove.RabbitMQ.Tests/RabbitMQMessageBus_Tests.cs b/test/Stove.RabbitMQ.Tests/RabbitMQMessageBus_Tests.cs new file mode 100644 index 0000000..56fa201 --- /dev/null +++ b/test/Stove.RabbitMQ.Tests/RabbitMQMessageBus_Tests.cs @@ -0,0 +1,142 @@ +using MassTransit; + +using NSubstitute; + +using Stove.MQ; +using Stove.RabbitMQ.RabbitMQ; +using Stove.TestBase; + +using Xunit; + +namespace Stove.RabbitMQ.Tests +{ + public class RabbitMQMessageBus_Tests : TestBaseWithLocalIocResolver + { + private readonly IBus _bus; + + public RabbitMQMessageBus_Tests() + { + _bus = Substitute.For(); + + Building(builder => + { + builder.RegisterServices(r => + { + r.Register(); + r.Register(ctx => _bus); + }); + }) + .Ok(); + } + + [Fact] + public void publish_object_should_work() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var messageBus = LocalResolver.Resolve(); + var message = new { Message = "Hi" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + messageBus.Publish(message); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + _bus.Received().Publish(message); + } + + [Fact] + public void publish_with_object_should_work() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var messageBus = LocalResolver.Resolve(); + var message = new { Message = "Hi" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + messageBus.Publish(message); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + _bus.Received().Publish(message); + } + + [Fact] + public void publish_with_TMessage_should_work() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var messageBus = LocalResolver.Resolve(); + var message = new RabbitMqTestMessage { Message = "Hi" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + messageBus.Publish(message); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + _bus.Received().Publish(message); + } + + [Fact] + public void publish_with_TMessage_as_object_should_work() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var messageBus = LocalResolver.Resolve(); + var message = new { Message = "Hi" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + messageBus.Publish(message); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + _bus.Received().Publish(message); + } + + [Fact] + public void publish_object_with_type_should_work() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var messageBus = LocalResolver.Resolve(); + var message = new RabbitMqTestMessage { Message = "Hi" }; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + messageBus.Publish(message, typeof(IRabbitMqTestMessage)); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + _bus.Received().Publish(message, typeof(IRabbitMqTestMessage)); + } + + private interface IRabbitMqTestMessage + { + string Message { get; set; } + } + + private class RabbitMqTestMessage : IRabbitMqTestMessage + { + public string Message { get; set; } + } + } +} diff --git a/test/Stove.RabbitMQ.Tests/Stove.RabbitMQ.Tests.xproj b/test/Stove.RabbitMQ.Tests/Stove.RabbitMQ.Tests.xproj new file mode 100644 index 0000000..96b9099 --- /dev/null +++ b/test/Stove.RabbitMQ.Tests/Stove.RabbitMQ.Tests.xproj @@ -0,0 +1,21 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + f024076f-a7aa-4b54-9f01-d3691a8bc988 + Stove.RabbitMQ.Tests + .\obj + .\bin\ + v4.6.1 + + + + 2.0 + + + diff --git a/test/Stove.RabbitMQ.Tests/StoveRabbitMQConfiguration_Tests.cs b/test/Stove.RabbitMQ.Tests/StoveRabbitMQConfiguration_Tests.cs new file mode 100644 index 0000000..a518243 --- /dev/null +++ b/test/Stove.RabbitMQ.Tests/StoveRabbitMQConfiguration_Tests.cs @@ -0,0 +1,63 @@ +using Autofac.Extras.IocManager; + +using Shouldly; + +using Stove.Configuration; +using Stove.RabbitMQ.RabbitMQ; +using Stove.TestBase; + +using Xunit; + +namespace Stove.RabbitMQ.Tests +{ + public class StoveRabbitMQConfiguration_Tests : TestBaseWithLocalIocResolver + { + public StoveRabbitMQConfiguration_Tests() + { + Building(builder => + { + builder.RegisterServices(r => + { + r.Register(Lifetime.Singleton); + r.Register(Lifetime.Singleton); + r.Register(Lifetime.Singleton); + }); + }).Ok(); + } + + [Fact] + public void extension_should_be_instantiatable() + { + LocalResolver.Resolve().StoveRabbitMQ().ShouldNotBeNull(); + } + + [Fact] + public void configuration_settings_should_work() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + IStoveRabbitMQConfiguration configuration = LocalResolver.Resolve().StoveRabbitMQ(); + configuration.HostAddress = "127.0.0.1"; + configuration.MaxRetryCount = 1; + configuration.Password = "123456"; + configuration.QueueName = "Default"; + configuration.UseRetryMechanism = true; + configuration.Username = "user"; + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + var configurationFromIoc = LocalResolver.Resolve(); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + configurationFromIoc.HostAddress.ShouldBe("127.0.0.1"); + configurationFromIoc.MaxRetryCount.ShouldBe(configuration.MaxRetryCount); + configurationFromIoc.Password.ShouldBe(configuration.Password); + configurationFromIoc.QueueName.ShouldBe(configuration.QueueName); + configurationFromIoc.UseRetryMechanism.ShouldBe(configuration.UseRetryMechanism); + } + } +} diff --git a/test/Stove.RabbitMQ.Tests/project.json b/test/Stove.RabbitMQ.Tests/project.json new file mode 100644 index 0000000..383ca8f --- /dev/null +++ b/test/Stove.RabbitMQ.Tests/project.json @@ -0,0 +1,17 @@ +{ + "version" : "1.0.0-*", + + "testRunner" : "xunit", + + "dependencies": { + "Stove": "0.0.10", + "Stove.RabbitMQ": "0.0.10-*", + "Stove.TestBase": "0.0.1-*" + }, + + "frameworks" : { + "net461" : { + + } + } +} diff --git a/test/Stove.TestBase/project.json b/test/Stove.TestBase/project.json index 4ead0c3..a505fd9 100644 --- a/test/Stove.TestBase/project.json +++ b/test/Stove.TestBase/project.json @@ -2,12 +2,12 @@ "version": "0.0.1-*", "dependencies": { - "FluentAssemblyScanner": "1.0.5", "dotnet-test-xunit": "2.2.0-preview2-build1029", - "xunit": "2.2.0-beta4-build3444", "NSubstitute": "1.10.0", "Shouldly": "2.8.2", - "Stove": "0.0.9" + "Stove": "0.0.10", + "FluentAssemblyScanner": "1.0.7", + "xunit": "2.2.0" }, "frameworks": { diff --git a/test/Stove.Tests.SampleApplication/BasicRepository_Tests.cs b/test/Stove.Tests.SampleApplication/BasicRepository_Tests.cs index 45cb84d..bf2017b 100644 --- a/test/Stove.Tests.SampleApplication/BasicRepository_Tests.cs +++ b/test/Stove.Tests.SampleApplication/BasicRepository_Tests.cs @@ -1,7 +1,12 @@ -using Shouldly; +using Autofac.Extras.IocManager; + +using Shouldly; using Stove.Domain.Repositories; using Stove.Domain.Uow; +using Stove.Events.Bus.Entities; +using Stove.Events.Bus.Handlers; +using Stove.Extensions; using Stove.Tests.SampleApplication.Domain.Entities; using Xunit; @@ -53,5 +58,51 @@ public void uow_rollback_should_work_with_repository_insert() userRepository.FirstOrDefault(x => x.Email == "ouzsykn@hotmail.com").ShouldBeNull(); } } + + [Fact] + public void uow_complete_handle_eventbus_should_work_with_repository_insert() + { + var uowManager = LocalResolver.Resolve(); + var userRepository = LocalResolver.Resolve>(); + + using (IUnitOfWorkCompleteHandle uow = uowManager.Begin()) + { + for (var i = 0; i < 1000; i++) + { + userRepository.Insert(new User + { + Email = "ouzsykn@hotmail.com", + Surname = "Sykn", + Name = "Oğuz" + }); + } + + uow.Complete(); + } + + using (IUnitOfWorkCompleteHandle uow = uowManager.Begin()) + { + userRepository.GetAll().ForEach(user => user.Surname = "Soykan"); + userRepository.Count(x => x.Email == "ouzsykn@hotmail.com").ShouldBe(1000); + userRepository.FirstOrDefault(x => x.Email == "ouzsykn@hotmail.com").ShouldNotBeNull(); + + uow.Complete(); + } + } + + public class UserCreatedEventHandler : IEventHandler>, + IEventHandler>, + ITransientDependency + { + public void HandleEvent(EntityCreatedEventData eventData) + { + User a = eventData.Entity; + } + + public void HandleEvent(EntityUpdatedEventData eventData) + { + User a = eventData.Entity; + } + } } } diff --git a/test/Stove.Tests.SampleApplication/project.json b/test/Stove.Tests.SampleApplication/project.json index cd6e531..ccef23c 100644 --- a/test/Stove.Tests.SampleApplication/project.json +++ b/test/Stove.Tests.SampleApplication/project.json @@ -5,8 +5,8 @@ "dependencies": { "Effort.EF6": "1.3.0", - "Stove.EntityFramework": "0.0.9-*", - "Stove.Mapster": "0.0.9-*", + "Stove.EntityFramework": "0.0.10-*", + "Stove.Mapster": "0.0.10-*", "Stove.TestBase": "0.0.1-*" }, diff --git a/test/Stove.Tests/Check_Tests.cs b/test/Stove.Tests/Check_Tests.cs new file mode 100644 index 0000000..38f5d79 --- /dev/null +++ b/test/Stove.Tests/Check_Tests.cs @@ -0,0 +1,277 @@ +using System; +using System.Collections.Generic; + +using NSubstitute; + +using Shouldly; + +using Xunit; + +namespace Stove.Tests +{ + public class Check_Tests + { + [Fact] + public void NotNull_should_throw_ArgumentNullException_when_value_is_null() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + string testString = null; + string parameterName = nameof(testString); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.NotNull(testString, parameterName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow(); + } + + [Fact] + public void NotNull_should_throw_ArgumentException_with_message_when_value_is_null_parametername_is_not_null() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + string testString = null; + string parameterName = nameof(testString); + string propertyName = nameof(testString); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.NotNull(testString, parameterName, propertyName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow(propertyName + " " + parameterName + " argument property is null!"); + } + + [Fact] + public void NotNullOrWhiteSpace_should_throw_exception_when_value_is_null() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + string testString = null; + string parameterName = nameof(testString); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.NotNullOrWhiteSpace(testString, parameterName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow($"{parameterName} can not be null, empty or white space!"); + } + + [Fact] + public void NotNullOrWhiteSpace_should_throw_exception_when_value_is_empty() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + string testString = string.Empty; + string parameterName = nameof(testString); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.NotNullOrWhiteSpace(testString, parameterName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow($"{parameterName} can not be null, empty or white space!"); + } + + [Fact] + public void NotNullOrWhiteSpace_should_throw_exception_when_value_is_whitespace() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var testString = " "; + string parameterName = nameof(testString); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.NotNullOrWhiteSpace(testString, parameterName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow($"{parameterName} can not be null, empty or white space!"); + } + + [Fact] + public void NotNullOrEmpty_should_throw_exception_when_value_is_null() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + ICollection testCollection = null; + string parameterName = nameof(testCollection); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.NotNullOrEmpty(testCollection, parameterName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow(parameterName + "is empty!"); + } + + [Fact] + public void NotNullOrEmpty_should_throw_exception_when_value_is_empty() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + ICollection testCollection = new List(); + string parameterName = nameof(testCollection); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.NotNullOrEmpty(testCollection, parameterName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow(parameterName + "is empty!"); + } + + [Fact] + public void NullButNotEmpty_should_throw_exception_when_value_is_null() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + string testString = string.Empty; + string parameterName = nameof(testString); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.NullButNotEmpty(testString, parameterName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow(parameterName + "is empty!"); + } + + [Fact] + public void HasNoNulls_should_throw_exception_when_value_is_null() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var testObjects = new List(); + testObjects.Add(new { Item = 1 }); + testObjects.Add(null); + string parameterName = nameof(testObjects); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.HasNoNulls(testObjects, parameterName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow(); + } + + [Fact] + public void IsDefined_should_throw_exception_when_value_is_not_an_enum() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var testNotEnum = Arg.Any(); + string parameterName = nameof(testNotEnum); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.IsDefined(testNotEnum, parameterName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow(parameterName + " is an invalid Enum!"); + } + + [Fact] + public void ValidEntityType_should_throw_exception_when_value_is_not_a_class() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + Type testValue = typeof(IEnumerable<>); + string parameterName = nameof(testValue); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.ValidEntityType(testValue, parameterName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow(parameterName + " is an invalid entity type!"); + } + + [Fact] + public void NotEmpty_should_throw_exception_when_value_is_null() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + string testValue = null; + string parameterName = nameof(testValue); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.NotEmpty(testValue, parameterName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow(parameterName + " can not be empty!"); + } + + [Fact] + public void NotEmpty_should_throw_exception_when_value_is_empty() + { + //----------------------------------------------------------------------------------------------------------- + // Arrange + //----------------------------------------------------------------------------------------------------------- + var testValue = " "; + string parameterName = nameof(testValue); + + //----------------------------------------------------------------------------------------------------------- + // Act + //----------------------------------------------------------------------------------------------------------- + Action check = () => Check.NotEmpty(testValue, parameterName); + + //----------------------------------------------------------------------------------------------------------- + // Assert + //----------------------------------------------------------------------------------------------------------- + check.ShouldThrow(parameterName + " can not be empty!"); + } + } +}