├── .gitattributes ├── .gitignore ├── LICENSE.md ├── readme.md └── src ├── CommandQueryExample.Common ├── BaseAsyncQuery.cs ├── BaseAsyncScalarQuery.cs ├── BaseCommand.cs ├── BaseQuery.cs ├── BaseScalarQuery.cs ├── CommandQueryExample.Common.csproj ├── DataContextFactory.cs ├── DisposableBase.cs ├── Extensions │ ├── AverageAsyncExtensions.cs │ ├── DbSetExtensions.cs │ ├── DispatcherExtensions.cs │ ├── EnumerableExtensions.cs │ ├── ExceptionExtensions.cs │ ├── LoggingExtensions.cs │ ├── ObjectExtensions.cs │ ├── QueryExtensions.cs │ ├── StringExtensions.cs │ ├── SumAsyncExtensions.cs │ └── TypeExtensions.cs ├── IAverageAsyncExtensionsUtil.cs ├── IDataContext.cs ├── IDbSetExtensionsUtil.cs ├── IDispatcher.cs ├── IQueryExtensionsUtil.cs ├── IStartupTask.cs ├── ISumAsyncExtensionsUtil.cs ├── Logger.cs ├── Properties │ └── AssemblyInfo.cs ├── ResharperAnnotationHelpers.cs ├── StandardCommands │ ├── AddCommand.cs │ ├── AddRangeCommand.cs │ ├── RemoveCommand.cs │ ├── RemoveRangeCommand.cs │ ├── UpdateCommand.cs │ └── UpdateRangeCommand.cs ├── StandardQueries │ ├── Async │ │ ├── FindAsyncQuery.cs │ │ ├── FirstAsyncQuery.cs │ │ ├── FirstOrDefaultAsyncQuery.cs │ │ ├── GetAllAsyncQuery.cs │ │ ├── SingleAsyncQuery.cs │ │ ├── SingleOrDefaultAsyncQuery.cs │ │ └── WhereAsyncQuery.cs │ ├── FindQuery.cs │ ├── FirstOrDefaultQuery.cs │ ├── FirstQuery.cs │ ├── GetAllQuery.cs │ ├── SingleOrDefaultQuery.cs │ ├── SingleQuery.cs │ └── WhereQuery.cs ├── Verify.cs └── packages.config ├── CommandQueryExample.Data ├── App.config ├── AverageAsyncExtensionsUtil.cs ├── CommandQueryExample.Data.csproj ├── ContextInitializer.cs ├── DataContext.cs ├── DataContextFactoryStartupTask.cs ├── DbSetExtensionsUtil.cs ├── Dispatcher.cs ├── Properties │ └── AssemblyInfo.cs ├── QueryExtensionsUtil.cs ├── SampleContext.cs ├── SumAsyncExtensionsUtil.cs └── packages.config ├── CommandQueryExample.Tests ├── App.config ├── CommandQueryExample.Tests.csproj ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── CommandQueryExample.sln ├── CommandQueryExample ├── App.config ├── CommandQueryExample.csproj ├── CreatePersonCommand.cs ├── GetPeopleByFirstNameQuery.cs ├── Log4Net.config ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config └── CommandQuerySample.Domain ├── CommandQuerySample.Domain.csproj ├── Person.cs └── Properties └── AssemblyInfo.cs /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #ignore thumbnails created by windows 2 | Thumbs.db 3 | #Ignore files build by Visual Studio 4 | *.obj 5 | *.exe 6 | *.pdb 7 | *.user 8 | *.aps 9 | *.pch 10 | *.vspscc 11 | *_i.c 12 | *_p.c 13 | *.ncb 14 | *.suo 15 | *.tlb 16 | *.tlh 17 | *.bak 18 | *.cache 19 | *.ilk 20 | *.log* 21 | *.mdf 22 | *.ldf 23 | [Bb]in 24 | [Dd]ebug*/ 25 | [Dd]eploy*/ 26 | *.lib 27 | *.sbr 28 | obj/ 29 | [Rr]elease*/ 30 | _ReSharper*/ 31 | [Tt]est[Rr]esult* 32 | [Pp]ackages*/ 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 H. Alan Stevens 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Command Query Example 2 | 3 | This project is an attempt to build a simple command and query data access system that I can use in my apps. 4 | It works by creating a thin wrapper around the Entity 5 | Framework DbContext. DbContext is a big smelly "god object." It tries to do too 6 | much and violates SRP. 7 | 8 | I have used an `IRepository` for years to abstract the DbContext away from my 9 | application code but it turns out that repositories aren't cool anymore and I've 10 | been doing it wrong (successfully) for years. It's all 11 | command and query objects these days. You can read all about why I'm wrong to use an 12 | `IRepository` in the links below. 13 | 14 | At this point, this project is just a thought experiment. I'd love to hear your 15 | feedback. Please feel free to code review this project and open issues for 16 | changes you think are merited. If you get really enthusiastic, you can send a 17 | pull request, but I would rather just get comments in the issues, for now. 18 | 19 | I borrowed some ideas from [Highway.Data] (https://github.com/HighwayFramework/Highway.Data), but my implementations are more 20 | simple. 21 | 22 | *Note: This is not an attempt to implement CQRS which is [a much more complex pattern] (http://www.udidahan.com/2009/12/09/clarified-cqrs/).* 23 | 24 | ## TODO: 25 | - **Write tests!** 26 | - Logging 27 | - Event hooks? 28 | 29 | ## Repository Hate Links: 30 | 31 | [Rob Conery] (http://rob.conery.io/2014/03/04/repositories-on-top-unitofwork-are-not-a-good-idea/) 32 | 33 | [Jimmy Bogard] (http://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/) 34 | 35 | [Jimmy Bogard again] (http://lostechies.com/jimmybogard/2009/09/11/wither-the-repository/) 36 | 37 | [Ayende] (http://ayende.com/blog/3955/repository-is-the-new-singleton) 38 | 39 | [Ayende again] (http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer) 40 | 41 | [Jon Smith] (http://www.thereformedprogrammer.net/is-the-repository-pattern-useful-with-entity-framework/) 42 | 43 | [Jon Smith again] (http://www.thereformedprogrammer.net/is-the-repository-pattern-useful-with-entity-framework-part-2/) 44 | 45 | [Isaac Abraham] (https://cockneycoder.wordpress.com/2013/04/07/why-entity-framework-renders-the-repository-pattern-obsolete/) 46 | 47 | [Khalid Abuhakmeh] (http://tech.pro/blog/1191/say-no-to-the-repository-pattern-in-your-dal) 48 | 49 | [Bertrand Le Roy] (http://weblogs.asp.net/bleroy/just-forget-that-repository-t-exists-please) 50 | 51 | [Ben Morris] (http://www.ben-morris.com/why-the-generic-repository-is-just-a-lazy-anti-pattern/) 52 | -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/BaseAsyncQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace CommandQueryExample.Common 7 | { 8 | public abstract class BaseAsyncQuery where T : class 9 | { 10 | protected Func, Task>> Query { private get; set; } 11 | 12 | public async Task> CallAsync(IQueryable set) 13 | { 14 | return await Query.Invoke(set); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/BaseAsyncScalarQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | 5 | namespace CommandQueryExample.Common 6 | { 7 | public abstract class BaseAsyncScalarQuery 8 | { 9 | protected Func, Task> Query { private get; set; } 10 | 11 | public async Task CallAsync(IQueryable set) 12 | { 13 | return await Query.Invoke(set); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/BaseCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace CommandQueryExample.Common 5 | { 6 | public abstract class BaseCommand 7 | { 8 | protected BaseCommand() 9 | { 10 | MarkAsModified = x => { }; 11 | MarkAsAdded = x => { }; 12 | MarkAsDeleted = x => { }; 13 | } 14 | 15 | public Action MarkAsModified { get; set; } 16 | public Action MarkAsAdded { get; set; } 17 | public Action MarkAsDeleted { get; set; } 18 | 19 | protected Action> Action { private get; set; } 20 | 21 | public void Execute(IQueryable set) 22 | { 23 | Action.Invoke(set); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/BaseQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace CommandQueryExample.Common 6 | { 7 | public abstract class BaseQuery where T : class 8 | { 9 | protected Func, IEnumerable> Query { private get; set; } 10 | 11 | public IEnumerable Call(IQueryable set) 12 | { 13 | return Query.Invoke(set); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/BaseScalarQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace CommandQueryExample.Common 5 | { 6 | public abstract class BaseScalarQuery 7 | { 8 | protected Func, T> Query { private get; set; } 9 | 10 | public virtual T Call(IQueryable set) 11 | { 12 | return Query.Invoke(set); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/CommandQueryExample.Common.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {91D84F63-79B8-4DC5-A822-EEA3E65C26A4} 8 | Library 9 | Properties 10 | CommandQueryExample.Common 11 | CommandQueryExample.Common 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 106 | -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/DataContextFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CommandQueryExample.Common.Extensions; 3 | 4 | namespace CommandQueryExample.Common 5 | { 6 | public static class DataContextFactory 7 | { 8 | // TODO: HAS 02/09/2015 Handle multiple data context classes. 9 | static Func _createDataContext; 10 | 11 | static WeakReference _currentContext; 12 | 13 | static readonly object _lock = new object(); 14 | 15 | public static IDataContext CurrentContext 16 | { 17 | get 18 | { 19 | lock (_lock) 20 | { 21 | if (_currentContext.IsNull()) throw new NullReferenceException("CurrentContext is null."); 22 | IDataContext context; 23 | _currentContext.TryGetTarget(out context); 24 | if (context.IsNull()) throw new NullReferenceException("CurrentContext is null."); 25 | if (context.IsDisposed) throw new ObjectDisposedException("CurrentContext has been disposed."); 26 | return context; 27 | } 28 | } 29 | private set 30 | { 31 | lock (_lock) 32 | { 33 | if (_currentContext.IsNotNull()) 34 | { 35 | IDataContext context; 36 | _currentContext.TryGetTarget(out context); 37 | 38 | if (context.IsNotNull() && !context.IsDisposed) 39 | throw new InvalidOperationException("CurrentContext has not been disposed."); 40 | } 41 | _currentContext = new WeakReference(value); 42 | } 43 | } 44 | } 45 | 46 | public static Func DataContextInitializer 47 | { 48 | set 49 | { 50 | _createDataContext = useTransaction => 51 | { 52 | CurrentContext = value(useTransaction); 53 | return CurrentContext; 54 | }; 55 | } 56 | } 57 | 58 | public static IDataContext CreateDataContext(bool useTransaction = false) 59 | { 60 | lock (_lock) 61 | { 62 | if (_createDataContext.IsNull()) 63 | throw new NullReferenceException("DataContextFactory.CreateDataContext is not properly configured."); 64 | 65 | if (_currentContext.IsNull()) return _createDataContext(useTransaction); 66 | 67 | IDataContext context; 68 | _currentContext.TryGetTarget(out context); 69 | 70 | if (context.IsNotNull() && !context.IsDisposed) 71 | throw new InvalidOperationException("CurrentContext has not been disposed."); 72 | 73 | return _createDataContext(useTransaction); 74 | } 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/DisposableBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace CommandQueryExample.Common 5 | { 6 | public abstract class DisposableBase : IDisposable 7 | { 8 | public bool IsDisposed { get; private set; } 9 | 10 | [DebuggerStepThrough] 11 | public void Dispose() 12 | { 13 | Dispose(true); 14 | GC.SuppressFinalize(this); 15 | } 16 | 17 | void Dispose(bool disposing) 18 | { 19 | if (!IsDisposed) OnDisposing(disposing); 20 | IsDisposed = true; 21 | } 22 | 23 | protected abstract void OnDisposing(bool disposing); 24 | 25 | ~DisposableBase() 26 | { 27 | Dispose(false); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Extensions/AverageAsyncExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace CommandQueryExample.Common.Extensions 8 | { 9 | public static class AverageAsyncExtensions 10 | { 11 | public static IAverageAsyncExtensionsUtil Util { get; set; } 12 | 13 | public static async Task AverageAsync(this IQueryable collection) 14 | { 15 | return await Util.AverageAsync(collection); 16 | } 17 | 18 | public static async Task AverageAsync(this IQueryable collection, CancellationToken cancellationToken) 19 | { 20 | return await Util.AverageAsync(collection, cancellationToken); 21 | } 22 | 23 | public static async Task AverageAsync(this IQueryable collection) 24 | { 25 | return await Util.AverageAsync(collection); 26 | } 27 | 28 | public static async Task AverageAsync(this IQueryable collection, CancellationToken cancellationToken) 29 | { 30 | return await Util.AverageAsync(collection, cancellationToken); 31 | } 32 | 33 | public static async Task AverageAsync(this IQueryable collection) 34 | { 35 | return await Util.AverageAsync(collection); 36 | } 37 | 38 | public static async Task AverageAsync(this IQueryable collection, CancellationToken cancellationToken) 39 | { 40 | return await Util.AverageAsync(collection, cancellationToken); 41 | } 42 | 43 | public static async Task AverageAsync(this IQueryable collection) 44 | { 45 | return await Util.AverageAsync(collection); 46 | } 47 | 48 | public static async Task AverageAsync(this IQueryable collection, CancellationToken cancellationToken) 49 | { 50 | return await Util.AverageAsync(collection, cancellationToken); 51 | } 52 | 53 | public static async Task AverageAsync(this IQueryable collection) 54 | { 55 | return await Util.AverageAsync(collection); 56 | } 57 | 58 | public static async Task AverageAsync(this IQueryable collection, CancellationToken cancellationToken) 59 | { 60 | return await Util.AverageAsync(collection, cancellationToken); 61 | } 62 | 63 | public static async Task AverageAsync(this IQueryable collection) 64 | { 65 | return await Util.AverageAsync(collection); 66 | } 67 | 68 | public static async Task AverageAsync(this IQueryable collection, CancellationToken cancellationToken) 69 | { 70 | return await Util.AverageAsync(collection, cancellationToken); 71 | } 72 | 73 | public static async Task AverageAsync(this IQueryable collection) 74 | { 75 | return await Util.AverageAsync(collection); 76 | } 77 | 78 | public static async Task AverageAsync(this IQueryable collection, CancellationToken cancellationToken) 79 | { 80 | return await Util.AverageAsync(collection, cancellationToken); 81 | } 82 | 83 | public static async Task AverageAsync(this IQueryable collection) 84 | { 85 | return await Util.AverageAsync(collection); 86 | } 87 | 88 | public static async Task AverageAsync(this IQueryable collection, CancellationToken cancellationToken) 89 | { 90 | return await Util.AverageAsync(collection, cancellationToken); 91 | } 92 | 93 | public static async Task AverageAsync(this IQueryable collection) 94 | { 95 | return await Util.AverageAsync(collection); 96 | } 97 | 98 | public static async Task AverageAsync(this IQueryable collection, CancellationToken cancellationToken) 99 | { 100 | return await Util.AverageAsync(collection, cancellationToken); 101 | } 102 | 103 | public static async Task AverageAsync(this IQueryable collection) 104 | { 105 | return await Util.AverageAsync(collection); 106 | } 107 | 108 | public static async Task AverageAsync(this IQueryable collection, CancellationToken cancellationToken) 109 | { 110 | return await Util.AverageAsync(collection, cancellationToken); 111 | } 112 | 113 | public static async Task AverageAsync(this IQueryable collection, Expression> selector) 114 | { 115 | return await Util.AverageAsync(collection, selector); 116 | } 117 | 118 | public static async Task AverageAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 119 | { 120 | return await Util.AverageAsync(collection, selector, cancellationToken); 121 | } 122 | 123 | public static async Task AverageAsync(this IQueryable collection, Expression> selector) 124 | { 125 | return await Util.AverageAsync(collection, selector); 126 | } 127 | 128 | public static async Task AverageAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 129 | { 130 | return await Util.AverageAsync(collection, selector, cancellationToken); 131 | } 132 | 133 | public static async Task AverageAsync(this IQueryable collection, Expression> selector) 134 | { 135 | return await Util.AverageAsync(collection, selector); 136 | } 137 | 138 | public static async Task AverageAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 139 | { 140 | return await Util.AverageAsync(collection, selector, cancellationToken); 141 | } 142 | 143 | public static async Task AverageAsync(this IQueryable collection, Expression> selector) 144 | { 145 | return await Util.AverageAsync(collection, selector); 146 | } 147 | 148 | public static async Task AverageAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 149 | { 150 | return await Util.AverageAsync(collection, selector, cancellationToken); 151 | } 152 | 153 | public static async Task AverageAsync(this IQueryable collection, Expression> selector) 154 | { 155 | return await Util.AverageAsync(collection, selector); 156 | } 157 | 158 | public static async Task AverageAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 159 | { 160 | return await Util.AverageAsync(collection, selector, cancellationToken); 161 | } 162 | 163 | public static async Task AverageAsync(this IQueryable collection, Expression> selector) 164 | { 165 | return await Util.AverageAsync(collection, selector); 166 | } 167 | 168 | public static async Task AverageAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 169 | { 170 | return await Util.AverageAsync(collection, selector, cancellationToken); 171 | } 172 | 173 | public static async Task AverageAsync(this IQueryable collection, Expression> selector) 174 | { 175 | return await Util.AverageAsync(collection, selector); 176 | } 177 | 178 | public static async Task AverageAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 179 | { 180 | return await Util.AverageAsync(collection, selector, cancellationToken); 181 | } 182 | 183 | public static async Task AverageAsync(this IQueryable collection, Expression> selector) 184 | { 185 | return await Util.AverageAsync(collection, selector); 186 | } 187 | 188 | public static async Task AverageAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 189 | { 190 | return await Util.AverageAsync(collection, selector, cancellationToken); 191 | } 192 | 193 | public static async Task AverageAsync(this IQueryable collection, Expression> selector) 194 | { 195 | return await Util.AverageAsync(collection, selector); 196 | } 197 | 198 | public static async Task AverageAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 199 | { 200 | return await Util.AverageAsync(collection, selector, cancellationToken); 201 | } 202 | 203 | public static async Task AverageAsync(this IQueryable collection, Expression> selector) 204 | { 205 | return await Util.AverageAsync(collection, selector); 206 | } 207 | 208 | public static async Task AverageAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 209 | { 210 | return await Util.AverageAsync(collection, selector, cancellationToken); 211 | } 212 | } 213 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Extensions/DbSetExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace CommandQueryExample.Common.Extensions 7 | { 8 | public static class DbSetExtensions 9 | { 10 | public static IDbSetExtensionsUtil Util { get; set; } 11 | 12 | public static T Add(this IQueryable collection, T entity) where T : class 13 | { 14 | return Util.Add(collection, entity); 15 | } 16 | 17 | public static IEnumerable AddRange(this IQueryable collection, IEnumerable entities) where T : class 18 | { 19 | return Util.AddRange(collection, entities); 20 | } 21 | 22 | public static T Attach(this IQueryable collection, T entity) where T : class 23 | { 24 | return Util.Attach(collection, entity); 25 | } 26 | 27 | public static T Create(this IQueryable collection) where T : class 28 | { 29 | return Util.Create(collection); 30 | } 31 | 32 | public static TDerivedType Create(this IQueryable collection) where T : class where TDerivedType : class, T 33 | { 34 | return Util.Create(collection); 35 | } 36 | 37 | public static T Find(this IQueryable collection, params object[] keyValues) where T : class 38 | { 39 | return Util.Find(collection, keyValues); 40 | } 41 | 42 | public static async Task FindAsync(this IQueryable collection, params object[] keyValues) where T : class 43 | { 44 | return await Util.FindAsync(collection, keyValues); 45 | } 46 | 47 | public static async Task FindAsync(this IQueryable collection, CancellationToken cancellationToken, params object[] keyValues) where T : class 48 | { 49 | return await Util.FindAsync(collection, cancellationToken, keyValues); 50 | } 51 | 52 | public static T Remove(this IQueryable collection, T entity) where T : class 53 | { 54 | return Util.Remove(collection, entity); 55 | } 56 | 57 | public static IEnumerable RemoveRange(this IQueryable collection, IEnumerable entities) where T : class 58 | { 59 | return Util.RemoveRange(collection, entities); 60 | } 61 | 62 | public static IEnumerable SqlQuery(this IQueryable collection, string sql, params object[] parameters) where T : class 63 | { 64 | return Util.SqlQuery(collection, sql, parameters); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Extensions/DispatcherExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CommandQueryExample.Common.StandardCommands; 3 | 4 | namespace CommandQueryExample.Common.Extensions 5 | { 6 | public static class DispatcherExtensions 7 | { 8 | public static void Remove(this IDispatcher dispatcher, T item) where T : class 9 | { 10 | dispatcher.QueueCommand(new RemoveCommand(item)); 11 | } 12 | 13 | public static void RemoveRange(this IDispatcher dispatcher, IEnumerable items) where T : class 14 | { 15 | dispatcher.QueueCommand(new RemoveRangeCommand(items)); 16 | } 17 | 18 | public static void Add(this IDispatcher dispatcher, T item) where T : class 19 | { 20 | dispatcher.QueueCommand(new AddCommand(item)); 21 | } 22 | 23 | public static void AddRange(this IDispatcher dispatcher, IEnumerable items) where T : class 24 | { 25 | dispatcher.QueueCommand(new AddRangeCommand(items)); 26 | } 27 | 28 | public static void Update(this IDispatcher dispatcher, T item) where T : class 29 | { 30 | dispatcher.QueueCommand(new UpdateCommand(item)); 31 | } 32 | 33 | public static void UpdateRange(this IDispatcher dispatcher, IEnumerable items) where T : class 34 | { 35 | dispatcher.QueueCommand(new UpdateRangeCommand(items)); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Extensions/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.Specialized; 5 | using System.Diagnostics; 6 | using System.Linq; 7 | 8 | namespace CommandQueryExample.Common.Extensions 9 | { 10 | public static class EnumerableExtensions 11 | { 12 | [DebuggerStepThrough] 13 | public static void RemoveWhere(this IList list, Func whereEvaluator) 14 | { 15 | for (var i = list.Count - 1; i >= 0; i--) if (whereEvaluator(list[i])) list.RemoveAt(i); 16 | } 17 | 18 | [DebuggerStepThrough] 19 | public static IEnumerable Each(this IEnumerable values, Action eachAction) 20 | { 21 | foreach (var item in values) eachAction(item); 22 | 23 | return values; 24 | } 25 | 26 | [DebuggerStepThrough] 27 | public static IEnumerable Each(this IEnumerable values, Action eachAction) 28 | { 29 | foreach (var item in values) eachAction(item); 30 | 31 | return values; 32 | } 33 | 34 | [DebuggerStepThrough] 35 | public static TReturn FirstValue(this IEnumerable enumerable, Func func) 36 | where TReturn : class 37 | { 38 | foreach (var item in enumerable) 39 | { 40 | var @object = func(item); 41 | if (@object != null) return @object; 42 | } 43 | 44 | return null; 45 | } 46 | 47 | [DebuggerStepThrough] 48 | public static IList AddMany(this IList list, params T[] items) 49 | { 50 | return list.AddRange(items); 51 | } 52 | 53 | [DebuggerStepThrough] 54 | public static IList AddRange(this IList list, IEnumerable items) 55 | { 56 | items.Each(list.Add); 57 | return list; 58 | } 59 | 60 | [DebuggerStepThrough] 61 | public static bool IsEqualTo(this IEnumerable actual, IEnumerable expected) 62 | { 63 | var actualList = actual.ToArray(); 64 | var expectedList = expected.ToArray(); 65 | 66 | if (actualList.Length != expectedList.Length) return false; 67 | 68 | for (var i = 0; i < actualList.Length; ++i) if (!actualList[i].Equals(expectedList[i])) return false; 69 | 70 | return true; 71 | } 72 | 73 | [DebuggerStepThrough] 74 | public static bool IsEmpty(this IEnumerable enumerable) 75 | { 76 | return (enumerable.IsNull() || !enumerable.Any()); 77 | } 78 | 79 | [DebuggerStepThrough] 80 | public static T GetValue(this NameValueCollection collection, string key) 81 | { 82 | return collection[key].As(); 83 | } 84 | 85 | [DebuggerStepThrough] 86 | public static int IndexOf(this IEnumerable items, T item) 87 | { 88 | return items.FindIndex(i => EqualityComparer.Default.Equals(item, i)); 89 | } 90 | 91 | [DebuggerStepThrough] 92 | static int FindIndex(this IEnumerable items, Func predicate) 93 | { 94 | Verify.NotNull(items, "items"); 95 | Verify.NotNull(predicate, "predicate"); 96 | 97 | var result = 0; 98 | foreach (var item in items) 99 | { 100 | if (predicate(item)) return result; 101 | result++; 102 | } 103 | return -1; 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Extensions/ExceptionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace CommandQueryExample.Common.Extensions 5 | { 6 | public static class ExceptionExtensions 7 | { 8 | [DebuggerStepThrough] 9 | public static string Serialize(this Exception ex) 10 | { 11 | return SerializeException(ex, ""); 12 | } 13 | 14 | static string SerializeException(Exception e, string exceptionMessage) 15 | { 16 | if (e.IsNull()) return string.Empty; 17 | 18 | exceptionMessage = "{0}{1}{2}\n{3}".FormatWith(exceptionMessage, exceptionMessage.IsEmpty() ? "" : "\n\n", 19 | e.Message, e.StackTrace); 20 | 21 | if (e.InnerException.IsNotNull()) exceptionMessage = SerializeException(e.InnerException, exceptionMessage); 22 | 23 | return exceptionMessage; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Extensions/LoggingExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace CommandQueryExample.Common.Extensions 6 | { 7 | public static class LoggingExtensions 8 | { 9 | public static Action ExceptionLogger = 10 | (loggingContext, ex) => Logger.Error(loggingContext, ex.Serialize()); 11 | 12 | [DebuggerStepThrough] 13 | public static void LogDebug(this object loggingContext, string message) 14 | { 15 | Logger.Debug(loggingContext, message); 16 | } 17 | 18 | [DebuggerStepThrough] 19 | public static void LogException(this object loggingContext, string message, Exception ex) 20 | { 21 | loggingContext.LogException(new Exception(message, ex)); 22 | } 23 | 24 | [DebuggerStepThrough] 25 | public static void LogException(this object loggingContext, Exception ex) 26 | { 27 | ExceptionLogger(loggingContext, ex); 28 | } 29 | 30 | [DebuggerStepThrough] 31 | public static void LogInfo(this object loggingContext, string message) 32 | { 33 | Logger.Info(loggingContext, message); 34 | } 35 | 36 | [DebuggerStepThrough] 37 | public static void LogWarn(this object loggingContext, string message) 38 | { 39 | Logger.Warn(loggingContext, message); 40 | } 41 | 42 | [DebuggerStepThrough] 43 | public static void LogFatal(this object loggingContext, string message) 44 | { 45 | Logger.Fatal(loggingContext, message); 46 | } 47 | 48 | [DebuggerStepThrough] 49 | public static void Trace(this object loggingContext, string message) 50 | { 51 | message = Regex.Replace(message, @"Password:(\w*)", "Password:***", RegexOptions.Multiline); 52 | 53 | Logger.Trace(message); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Extensions/ObjectExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using CommandQueryExample.Common.JetBrains.Annotations; 4 | 5 | namespace CommandQueryExample.Common.Extensions 6 | { 7 | public static class ObjectExtensions 8 | { 9 | [DebuggerStepThrough] 10 | public static bool IsTypeOf(this object value) 11 | { 12 | return value.GetType() == typeof (T); 13 | } 14 | 15 | [DebuggerStepThrough] 16 | public static bool IsNot(this object value) 17 | { 18 | return !(value is T); 19 | } 20 | 21 | [DebuggerStepThrough] 22 | public static bool Is(this object value) 23 | { 24 | return value is T; 25 | } 26 | 27 | [DebuggerStepThrough] 28 | [ContractAnnotation("null => true")] 29 | public static bool IsNull(this object value) 30 | { 31 | return ReferenceEquals(value, null); 32 | } 33 | 34 | [DebuggerStepThrough] 35 | [ContractAnnotation("null => false")] 36 | public static bool IsNotNull(this object value) 37 | { 38 | return !ReferenceEquals(value, null); 39 | } 40 | 41 | [DebuggerStepThrough] 42 | public static T As(this object value) 43 | { 44 | var result = default(T); 45 | 46 | if (value.IsNull()) return result; 47 | 48 | //if (value is String && value.ToString().Blank()) return (T) (String.Empty as object); 49 | 50 | try 51 | { 52 | if (result is String) return (T) (Convert.ToString(value) as object); 53 | 54 | if (result is ValueType) 55 | { 56 | if (result is Boolean) return (T) (Convert.ToBoolean(value) as object); 57 | if (result is Byte) return (T) (Convert.ToByte(value) as object); 58 | if (result is Char) return (T) (Convert.ToChar(value) as object); 59 | if (result is Decimal) return (T) (Convert.ToDecimal(value) as object); 60 | if (result is Double) return (T) (Convert.ToDouble(value) as object); 61 | if (result is Int16) return (T) (Convert.ToInt16(value) as object); 62 | if (result is Int32) return (T) (Convert.ToInt32(value) as object); 63 | if (result is Int64) return (T) (Convert.ToInt64(value) as object); 64 | if (result is SByte) return (T) (Convert.ToSByte(value) as object); 65 | if (result is Single) return (T) (Convert.ToSingle(value) as object); 66 | if (result is UInt16) return (T) (Convert.ToUInt16(value) as object); 67 | if (result is UInt32) return (T) (Convert.ToUInt32(value) as object); 68 | if (result is UInt64) return (T) (Convert.ToUInt64(value) as object); 69 | if (result is Guid) return (T) (new Guid(value.ToString()) as object); 70 | if (result is DateTime) 71 | { 72 | try 73 | { 74 | return (T) (Convert.ToDateTime(value) as object); 75 | } 76 | catch (InvalidCastException) 77 | { 78 | return (T) (DateTime.Parse(value.ToString()) as object); 79 | } 80 | } 81 | } 82 | result = (T) value; 83 | } 84 | catch (InvalidCastException ex) 85 | { 86 | LogException(ex); 87 | } 88 | catch (FormatException ex) 89 | { 90 | LogException(ex); 91 | } 92 | catch (ArgumentNullException ex) 93 | { 94 | LogException(ex); 95 | } 96 | catch (OverflowException ex) 97 | { 98 | LogException(ex); 99 | } 100 | 101 | return result; 102 | } 103 | 104 | static void LogException(Exception ex) 105 | { 106 | // Log the exception and return the default value. 107 | typeof (ObjectExtensions).LogException(ex); 108 | Debug.Assert(false, "Failed to convert type."); 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Extensions/QueryExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace CommandQueryExample.Common.Extensions 9 | { 10 | public static class QueryExtensions 11 | { 12 | public static IQueryExtensionsUtil Util { get; set; } 13 | 14 | public static async Task AllAsync(this IQueryable collection, Expression> where, T item) where T : class 15 | { 16 | return await Util.AllAsync(collection, where); 17 | } 18 | 19 | public static async Task AllAsync(this IQueryable collection, Expression> where, T item, CancellationToken cancellationToken) where T : class 20 | { 21 | return await Util.AllAsync(collection, where, cancellationToken); 22 | } 23 | 24 | public static async Task AnyAsync(this IQueryable collection) where T : class 25 | { 26 | return await Util.AnyAsync(collection); 27 | } 28 | 29 | public static async Task AnyAsync(this IQueryable collection, CancellationToken cancellationToken) where T : class 30 | { 31 | return await Util.AnyAsync(collection, cancellationToken); 32 | } 33 | 34 | public static async Task AnyAsync(this IQueryable collection, Expression> where) where T : class 35 | { 36 | return await Util.AnyAsync(collection, where); 37 | } 38 | 39 | public static async Task AnyAsync(this IQueryable collection, Expression> where, CancellationToken cancellationToken) where T : class 40 | { 41 | return await Util.AnyAsync(collection, where, cancellationToken); 42 | } 43 | 44 | public static IQueryable AsNoTracking(this IQueryable collection) where T : class 45 | { 46 | return Util.AsNoTracking(collection); 47 | } 48 | 49 | public static async Task ContainsAsync(this IQueryable collection, T item) where T : class 50 | { 51 | await Util.ContainsAsync(collection, item); 52 | } 53 | 54 | public static async Task ContainsAsync(this IQueryable collection, T item, CancellationToken cancellationToken) where T : class 55 | { 56 | return await Util.ContainsAsync(collection, item, cancellationToken); 57 | } 58 | 59 | public static async Task CountAsync(this IQueryable collection) where T : class 60 | { 61 | return await Util.CountAsync(collection); 62 | } 63 | 64 | public static async Task CountAsync(this IQueryable collection, CancellationToken cancellationToken) where T : class 65 | { 66 | return await Util.CountAsync(collection, cancellationToken); 67 | } 68 | 69 | public static async Task CountAsync(this IQueryable collection, Expression> where) where T : class 70 | { 71 | return await Util.CountAsync(collection, where); 72 | } 73 | 74 | public static async Task CountAsync(this IQueryable collection, Expression> where, CancellationToken cancellationToken) where T : class 75 | { 76 | return await Util.CountAsync(collection, where, cancellationToken); 77 | } 78 | 79 | public static async Task FirstAsync(this IQueryable collection) where T : class 80 | { 81 | return await Util.FirstAsync(collection); 82 | } 83 | 84 | public static async Task FirstAsync(this IQueryable collection, CancellationToken cancellationToken) where T : class 85 | { 86 | return await Util.FirstAsync(collection, cancellationToken); 87 | } 88 | 89 | public static async Task FirstAsync(this IQueryable collection, Expression> where) where T : class 90 | { 91 | return await Util.FirstAsync(collection, where); 92 | } 93 | 94 | public static async Task FirstAsync(this IQueryable collection, Expression> where, CancellationToken cancellationToken) where T : class 95 | { 96 | return await Util.FirstAsync(collection, where, cancellationToken); 97 | } 98 | 99 | public static async Task FirstOrDefaultAsync(this IQueryable collection) where T : class 100 | { 101 | return await Util.FirstOrDefaultAsync(collection); 102 | } 103 | 104 | public static async Task FirstOrDefaultAsync(this IQueryable collection, CancellationToken cancellationToken) where T : class 105 | { 106 | return await Util.FirstOrDefaultAsync(collection, cancellationToken); 107 | } 108 | 109 | public static async Task FirstOrDefaultAsync(this IQueryable collection, Expression> where) where T : class 110 | { 111 | return await Util.FirstOrDefaultAsync(collection, where); 112 | } 113 | 114 | public static async Task FirstOrDefaultAsync(this IQueryable collection, Expression> where, CancellationToken cancellationToken) where T : class 115 | { 116 | return await Util.FirstOrDefaultAsync(collection, where,cancellationToken); 117 | } 118 | 119 | public static async Task ForEachAsync(this IQueryable collection, Action action) where T : class 120 | { 121 | await Util.ForEachAsync(collection, action); 122 | } 123 | 124 | public static async Task ForEachAsync(this IQueryable collection, Action action, CancellationToken cancellationToken) where T : class 125 | { 126 | await Util.ForEachAsync(collection, action, cancellationToken); 127 | } 128 | 129 | public static IQueryable Include(this IQueryable collection, string path) where T : class 130 | { 131 | return Util.Include(collection, path); 132 | } 133 | 134 | public static IQueryable Include(this IQueryable collection, Expression> path) where T : class 135 | { 136 | return Util.Include(collection, path); 137 | } 138 | 139 | public static void Load(this IQueryable collection) where T : class 140 | { 141 | Util.Load(collection); 142 | } 143 | 144 | public static async Task LoadAsync(this IQueryable collection) where T : class 145 | { 146 | await Util.LoadAsync(collection); 147 | } 148 | 149 | public static async Task LoadAsync(this IQueryable collection, CancellationToken cancellationToken) where T : class 150 | { 151 | await Util.LoadAsync(collection, cancellationToken); 152 | } 153 | 154 | public static async Task LongCountAsync(this IQueryable collection) where T : class 155 | { 156 | return await Util.LongCountAsync(collection); 157 | } 158 | 159 | public static async Task LongCountAsync(this IQueryable collection, CancellationToken cancellationToken) where T : class 160 | { 161 | return await Util.LongCountAsync(collection, cancellationToken); 162 | } 163 | 164 | public static async Task LongCountAsync(this IQueryable collection, Expression> where) where T : class 165 | { 166 | return await Util.LongCountAsync(collection, where); 167 | } 168 | 169 | public static async Task LongCountAsync(this IQueryable collection, Expression> where, CancellationToken cancellationToken) where T : class 170 | { 171 | return await Util.LongCountAsync(collection, where, cancellationToken); 172 | } 173 | 174 | public static async Task MaxAsync(this IQueryable collection) where T : class 175 | { 176 | return await Util.MaxAsync(collection); 177 | } 178 | 179 | public static async Task MaxAsync(this IQueryable collection, CancellationToken cancellationToken) where T : class 180 | { 181 | return await Util.MaxAsync(collection, cancellationToken); 182 | } 183 | 184 | public static async Task MaxAsync(this IQueryable collection, Expression> where) where T : class 185 | { 186 | return await Util.MaxAsync(collection, where); 187 | } 188 | 189 | public static async Task MaxAsync(this IQueryable collection, Expression> where, CancellationToken cancellationToken) where T : class 190 | { 191 | return await Util.MaxAsync(collection, where, cancellationToken); 192 | } 193 | 194 | public static async Task MinAsync(this IQueryable collection) where T : class 195 | { 196 | return await Util.MinAsync(collection); 197 | } 198 | 199 | public static async Task MinAsync(this IQueryable collection, CancellationToken cancellationToken) where T : class 200 | { 201 | return await Util.MinAsync(collection, cancellationToken); 202 | } 203 | 204 | public static async Task MinAsync(this IQueryable collection, Expression> where) where T : class 205 | { 206 | return await Util.MinAsync(collection, where); 207 | } 208 | 209 | public static async Task MinAsync(this IQueryable collection, Expression> where, CancellationToken cancellationToken) where T : class 210 | { 211 | return await Util.MinAsync(collection, where, cancellationToken); 212 | } 213 | 214 | public static async Task SingleAsync(this IQueryable collection) where T : class 215 | { 216 | return await Util.SingleAsync(collection); 217 | } 218 | 219 | public static async Task SingleAsync(this IQueryable collection, CancellationToken cancellationToken) where T : class 220 | { 221 | return await Util.SingleAsync(collection, cancellationToken); 222 | } 223 | 224 | public static async Task SingleAsync(this IQueryable collection, Expression> where) where T : class 225 | { 226 | return await Util.SingleAsync(collection, where); 227 | } 228 | 229 | public static async Task SingleAsync(this IQueryable collection, Expression> where, CancellationToken cancellationToken) where T : class 230 | { 231 | return await Util.SingleAsync(collection, where, cancellationToken); 232 | } 233 | 234 | public static async Task SingleOrDefaultAsync(this IQueryable collection) where T : class 235 | { 236 | return await Util.SingleOrDefaultAsync(collection); 237 | } 238 | 239 | public static async Task SingleOrDefaultAsync(this IQueryable collection, CancellationToken cancellationToken) where T : class 240 | { 241 | return await Util.SingleOrDefaultAsync(collection, cancellationToken); 242 | } 243 | 244 | public static async Task SingleOrDefaultAsync(this IQueryable collection, Expression> where) where T : class 245 | { 246 | return await Util.SingleOrDefaultAsync(collection, where); 247 | } 248 | 249 | public static async Task SingleOrDefaultAsync(this IQueryable collection, Expression> where, CancellationToken cancellationToken) where T : class 250 | { 251 | return await Util.SingleOrDefaultAsync(collection, where, cancellationToken); 252 | } 253 | 254 | public static IQueryable Skip(this IQueryable collection, Expression> countAccesor) where T : class 255 | { 256 | return Util.Skip(collection, countAccesor); 257 | } 258 | 259 | public static IQueryable Take(this IQueryable collection, Expression> countAccesor) where T : class 260 | { 261 | return Util.Take(collection, countAccesor); 262 | } 263 | 264 | public static async Task ToArrayAsync(this IQueryable collection) where T : class 265 | { 266 | return await Util.ToArrayAsync(collection); 267 | } 268 | 269 | public static async Task ToArrayAsync(this IQueryable collection, CancellationToken cancellationToken) where T : class 270 | { 271 | return await Util.ToArrayAsync(collection, cancellationToken); 272 | } 273 | 274 | public static async Task> ToDictionaryAsync(this IQueryable collection, Func keySelector) where T : class 275 | { 276 | return await Util.ToDictionaryAsync(collection, keySelector); 277 | } 278 | 279 | public static async Task> ToDictionaryAsync(this IQueryable collection, Func keySelector, CancellationToken cancellationToken) where T : class 280 | { 281 | return await Util.ToDictionaryAsync(collection, keySelector, cancellationToken); 282 | } 283 | 284 | public static async Task> ToDictionaryAsync(this IQueryable collection, Func keySelector, IEqualityComparer comparer ) where T : class 285 | { 286 | return await Util.ToDictionaryAsync(collection, keySelector, comparer); 287 | } 288 | 289 | public static async Task> ToDictionaryAsync(this IQueryable collection, Func keySelector, IEqualityComparer comparer , CancellationToken cancellationToken) where T : class 290 | { 291 | return await Util.ToDictionaryAsync(collection, keySelector, comparer, cancellationToken); 292 | } 293 | 294 | public static async Task> ToDictionaryAsync(this IQueryable collection, Func keySelector, Func elementSelector) where T : class 295 | { 296 | return await Util.ToDictionaryAsync(collection, keySelector, elementSelector); 297 | } 298 | 299 | public static async Task> ToDictionaryAsync(this IQueryable collection, Func keySelector, Func elementSelector, CancellationToken cancellationToken) where T : class 300 | { 301 | return await Util.ToDictionaryAsync(collection, keySelector, elementSelector, cancellationToken); 302 | } 303 | 304 | public static async Task> ToDictionaryAsync(this IQueryable collection, Func keySelector, Func elementSelector, IEqualityComparer comparer ) where T : class 305 | { 306 | return await Util.ToDictionaryAsync(collection, keySelector, elementSelector, comparer); 307 | } 308 | 309 | public static async Task> ToDictionaryAsync(this IQueryable collection, Func keySelector, Func elementSelector, IEqualityComparer comparer , CancellationToken cancellationToken) where T : class 310 | { 311 | return await Util.ToDictionaryAsync(collection, keySelector, elementSelector, comparer, cancellationToken); 312 | } 313 | 314 | public static async Task> ToListAsync(this IQueryable collection) where T : class 315 | { 316 | return await Util.ToListAsync(collection); 317 | } 318 | 319 | public static async Task> ToListAsync(this IQueryable collection, CancellationToken cancellationToken) where T : class 320 | { 321 | return await Util.ToListAsync(collection, cancellationToken); 322 | } 323 | } 324 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Extensions/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Globalization; 5 | using System.Linq; 6 | using System.Security.Cryptography; 7 | using System.Text; 8 | using System.Threading; 9 | 10 | namespace CommandQueryExample.Common.Extensions 11 | { 12 | public static class StringExtensions 13 | { 14 | [DebuggerStepThrough] 15 | public static string ToProperCase(this string value) 16 | { 17 | Verify.NotEmpty(value, "value"); 18 | return Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(value.ToLower()); 19 | } 20 | 21 | [DebuggerStepThrough] 22 | public static bool Blank(this string value) 23 | { 24 | return String.IsNullOrWhiteSpace(value); 25 | } 26 | 27 | [DebuggerStepThrough] 28 | public static bool IsNotBlank(this string value) 29 | { 30 | return !String.IsNullOrWhiteSpace(value); 31 | } 32 | 33 | [DebuggerStepThrough] 34 | public static string FormatWith(this string stringFormat, params object[] args) 35 | { 36 | return String.Format(CultureInfo.InvariantCulture, stringFormat, args); 37 | } 38 | 39 | [DebuggerStepThrough] 40 | public static string FormatSQL(this string stringFormat, params object[] args) 41 | { 42 | var strings = Array.ConvertAll(args, a => a.ToString().SanitizeSQL()); 43 | return String.Format(CultureInfo.InvariantCulture, stringFormat, strings); 44 | } 45 | 46 | [DebuggerStepThrough] 47 | public static string CalculateHash(this string value) 48 | { 49 | Verify.NotEmpty(value, "value"); 50 | 51 | var data = Encoding.UTF8.GetBytes(value); 52 | var hash = data.CalculateHash(); 53 | 54 | return hash.ToBase64(); 55 | } 56 | 57 | [DebuggerStepThrough] 58 | public static byte[] CalculateHash(this byte[] value) 59 | { 60 | Verify.NotEmpty(value, "value"); 61 | 62 | using (var hashAlgorithm = HMAC.Create()) 63 | { 64 | var hash = hashAlgorithm.ComputeHash(value); 65 | 66 | return hash; 67 | } 68 | } 69 | 70 | [DebuggerStepThrough] 71 | public static string CalculateMd5Hash(this string value) 72 | { 73 | Verify.NotEmpty(value, "value"); 74 | 75 | using (var md5 = MD5.Create()) 76 | { 77 | var data = Encoding.UTF8.GetBytes(value); 78 | var hash = md5.ComputeHash(data); 79 | 80 | return hash.ToBase64(); 81 | } 82 | } 83 | 84 | [DebuggerStepThrough] 85 | public static string Base64ToHex(this string base64) 86 | { 87 | var hashBytes = Convert.FromBase64String(base64); 88 | 89 | return hashBytes.ToHex(); 90 | } 91 | 92 | [DebuggerStepThrough] 93 | public static string HexToBase64(this string hex) 94 | { 95 | var hashBytes = HexToBinary(hex); 96 | 97 | return Convert.ToBase64String(hashBytes); 98 | } 99 | 100 | [DebuggerStepThrough] 101 | public static Byte[] HexToBinary(this string hex) 102 | { 103 | var numberChars = hex.Length; 104 | if (numberChars%2 == 1) hex = '0' + hex; 105 | var bytes = new byte[numberChars/2]; 106 | for (var i = 0; i < numberChars; i += 2) bytes[i/2] = Convert.ToByte(hex.Substring(i, 2), 16); 107 | return bytes; 108 | } 109 | 110 | [DebuggerStepThrough] 111 | public static string ToHex(this byte[] input) 112 | { 113 | return BitConverter.ToString(input).Replace("-", string.Empty); 114 | } 115 | 116 | [DebuggerStepThrough] 117 | public static string ToBase64(this byte[] input) 118 | { 119 | return Convert.ToBase64String(input); 120 | } 121 | 122 | [DebuggerStepThrough] 123 | public static T ToEnum(this string value, T defaultValue) where T : IComparable, IFormattable 124 | { 125 | var convertedValue = defaultValue; 126 | 127 | if (value.IsNotBlank()) 128 | { 129 | try 130 | { 131 | convertedValue = (T) Enum.Parse(typeof (T), value.Trim(), true); 132 | } 133 | catch (ArgumentException) {} 134 | } 135 | 136 | return convertedValue; 137 | } 138 | 139 | [DebuggerStepThrough] 140 | public static string Join(this IEnumerable values, string separator = null) 141 | { 142 | return Join(values.ToArray(), separator); 143 | } 144 | 145 | [DebuggerStepThrough] 146 | public static string Join(this string[] values, string separator = null) 147 | { 148 | if (separator.IsNull()) separator = ","; 149 | return String.Join(separator, values); 150 | } 151 | 152 | [DebuggerStepThrough] 153 | public static string SanitizeSQL(this string value) 154 | { 155 | return value.Replace("'", "''").Replace("\\", "\\\\"); 156 | } 157 | } 158 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Extensions/SumAsyncExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace CommandQueryExample.Common.Extensions 8 | { 9 | public static class SumAsyncExtensions 10 | { 11 | public static ISumAsyncExtensionsUtil Util { get; set; } 12 | 13 | public static async Task SumAsync(this IQueryable collection) 14 | { 15 | return await Util.SumAsync(collection); 16 | } 17 | 18 | public static async Task SumAsync(this IQueryable collection, CancellationToken cancellationToken) 19 | { 20 | return await Util.SumAsync(collection, cancellationToken); 21 | } 22 | 23 | public static async Task SumAsync(this IQueryable collection) 24 | { 25 | return await Util.SumAsync(collection); 26 | } 27 | 28 | public static async Task SumAsync(this IQueryable collection, CancellationToken cancellationToken) 29 | { 30 | return await Util.SumAsync(collection, cancellationToken); 31 | } 32 | 33 | public static async Task SumAsync(this IQueryable collection) 34 | { 35 | return await Util.SumAsync(collection); 36 | } 37 | 38 | public static async Task SumAsync(this IQueryable collection, CancellationToken cancellationToken) 39 | { 40 | return await Util.SumAsync(collection, cancellationToken); 41 | } 42 | 43 | public static async Task SumAsync(this IQueryable collection) 44 | { 45 | return await Util.SumAsync(collection); 46 | } 47 | 48 | public static async Task SumAsync(this IQueryable collection, CancellationToken cancellationToken) 49 | { 50 | return await Util.SumAsync(collection, cancellationToken); 51 | } 52 | 53 | public static async Task SumAsync(this IQueryable collection) 54 | { 55 | return await Util.SumAsync(collection); 56 | } 57 | 58 | public static async Task SumAsync(this IQueryable collection, CancellationToken cancellationToken) 59 | { 60 | return await Util.SumAsync(collection, cancellationToken); 61 | } 62 | 63 | public static async Task SumAsync(this IQueryable collection) 64 | { 65 | return await Util.SumAsync(collection); 66 | } 67 | 68 | public static async Task SumAsync(this IQueryable collection, CancellationToken cancellationToken) 69 | { 70 | return await Util.SumAsync(collection, cancellationToken); 71 | } 72 | 73 | public static async Task SumAsync(this IQueryable collection) 74 | { 75 | return await Util.SumAsync(collection); 76 | } 77 | 78 | public static async Task SumAsync(this IQueryable collection, CancellationToken cancellationToken) 79 | { 80 | return await Util.SumAsync(collection, cancellationToken); 81 | } 82 | 83 | public static async Task SumAsync(this IQueryable collection) 84 | { 85 | return await Util.SumAsync(collection); 86 | } 87 | 88 | public static async Task SumAsync(this IQueryable collection, CancellationToken cancellationToken) 89 | { 90 | return await Util.SumAsync(collection, cancellationToken); 91 | } 92 | 93 | public static async Task SumAsync(this IQueryable collection) 94 | { 95 | return await Util.SumAsync(collection); 96 | } 97 | 98 | public static async Task SumAsync(this IQueryable collection, CancellationToken cancellationToken) 99 | { 100 | return await Util.SumAsync(collection, cancellationToken); 101 | } 102 | 103 | public static async Task SumAsync(this IQueryable collection) 104 | { 105 | return await Util.SumAsync(collection); 106 | } 107 | 108 | public static async Task SumAsync(this IQueryable collection, CancellationToken cancellationToken) 109 | { 110 | return await Util.SumAsync(collection, cancellationToken); 111 | } 112 | 113 | public static async Task SumAsync(this IQueryable collection, Expression> selector) 114 | { 115 | return await Util.SumAsync(collection, selector); 116 | } 117 | 118 | public static async Task SumAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 119 | { 120 | return await Util.SumAsync(collection, selector, cancellationToken); 121 | } 122 | 123 | public static async Task SumAsync(this IQueryable collection, Expression> selector) 124 | { 125 | return await Util.SumAsync(collection, selector); 126 | } 127 | 128 | public static async Task SumAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 129 | { 130 | return await Util.SumAsync(collection, selector, cancellationToken); 131 | } 132 | 133 | public static async Task SumAsync(this IQueryable collection, Expression> selector) 134 | { 135 | return await Util.SumAsync(collection, selector); 136 | } 137 | 138 | public static async Task SumAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 139 | { 140 | return await Util.SumAsync(collection, selector, cancellationToken); 141 | } 142 | 143 | public static async Task SumAsync(this IQueryable collection, Expression> selector) 144 | { 145 | return await Util.SumAsync(collection, selector); 146 | } 147 | 148 | public static async Task SumAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 149 | { 150 | return await Util.SumAsync(collection, selector, cancellationToken); 151 | } 152 | 153 | public static async Task SumAsync(this IQueryable collection, Expression> selector) 154 | { 155 | return await Util.SumAsync(collection, selector); 156 | } 157 | 158 | public static async Task SumAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 159 | { 160 | return await Util.SumAsync(collection, selector, cancellationToken); 161 | } 162 | 163 | public static async Task SumAsync(this IQueryable collection, Expression> selector) 164 | { 165 | return await Util.SumAsync(collection, selector); 166 | } 167 | 168 | public static async Task SumAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 169 | { 170 | return await Util.SumAsync(collection, selector, cancellationToken); 171 | } 172 | 173 | public static async Task SumAsync(this IQueryable collection, Expression> selector) 174 | { 175 | return await Util.SumAsync(collection, selector); 176 | } 177 | 178 | public static async Task SumAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 179 | { 180 | return await Util.SumAsync(collection, selector, cancellationToken); 181 | } 182 | 183 | public static async Task SumAsync(this IQueryable collection, Expression> selector) 184 | { 185 | return await Util.SumAsync(collection, selector); 186 | } 187 | 188 | public static async Task SumAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 189 | { 190 | return await Util.SumAsync(collection, selector, cancellationToken); 191 | } 192 | 193 | public static async Task SumAsync(this IQueryable collection, Expression> selector) 194 | { 195 | return await Util.SumAsync(collection, selector); 196 | } 197 | 198 | public static async Task SumAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 199 | { 200 | return await Util.SumAsync(collection, selector, cancellationToken); 201 | } 202 | 203 | public static async Task SumAsync(this IQueryable collection, Expression> selector) 204 | { 205 | return await Util.SumAsync(collection, selector); 206 | } 207 | 208 | public static async Task SumAsync(this IQueryable collection, Expression> selector, CancellationToken cancellationToken) 209 | { 210 | return await Util.SumAsync(collection, selector, cancellationToken); 211 | } 212 | } 213 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Extensions/TypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | 5 | namespace CommandQueryExample.Common.Extensions 6 | { 7 | public static class TypeExtensions 8 | { 9 | [DebuggerStepThrough] 10 | public static bool TryGetInterface(this Type type, out Type interfaceType) 11 | { 12 | interfaceType = type.GetInterfaces().FirstOrDefault(t => t == typeof (T)); 13 | 14 | return interfaceType != null; 15 | } 16 | 17 | [DebuggerStepThrough] 18 | public static T Create(this Type type) where T : class 19 | { 20 | return type.Create() as T; 21 | } 22 | 23 | [DebuggerStepThrough] 24 | public static object Create(this Type type) 25 | { 26 | return Activator.CreateInstance(type); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/IAverageAsyncExtensionsUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace CommandQueryExample.Common 8 | { 9 | public interface IAverageAsyncExtensionsUtil : IStartupTask 10 | { 11 | Task AverageAsync(IQueryable collection); 12 | 13 | Task AverageAsync(IQueryable collection, CancellationToken cancellationToken); 14 | 15 | Task AverageAsync(IQueryable collection); 16 | 17 | Task AverageAsync(IQueryable collection, CancellationToken cancellationToken); 18 | 19 | Task AverageAsync(IQueryable collection); 20 | 21 | Task AverageAsync(IQueryable collection, CancellationToken cancellationToken); 22 | 23 | Task AverageAsync(IQueryable collection); 24 | 25 | Task AverageAsync(IQueryable collection, CancellationToken cancellationToken); 26 | 27 | Task AverageAsync(IQueryable collection); 28 | 29 | Task AverageAsync(IQueryable collection, CancellationToken cancellationToken); 30 | 31 | Task AverageAsync(IQueryable collection); 32 | 33 | Task AverageAsync(IQueryable collection, CancellationToken cancellationToken); 34 | 35 | Task AverageAsync(IQueryable collection); 36 | 37 | Task AverageAsync(IQueryable collection, CancellationToken cancellationToken); 38 | 39 | Task AverageAsync(IQueryable collection); 40 | 41 | Task AverageAsync(IQueryable collection, CancellationToken cancellationToken); 42 | 43 | Task AverageAsync(IQueryable collection); 44 | 45 | Task AverageAsync(IQueryable collection, CancellationToken cancellationToken); 46 | 47 | Task AverageAsync(IQueryable collection); 48 | 49 | Task AverageAsync(IQueryable collection, CancellationToken cancellationToken); 50 | 51 | Task AverageAsync(IQueryable collection, Expression> selector); 52 | 53 | Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 54 | 55 | Task AverageAsync(IQueryable collection, Expression> selector); 56 | 57 | Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 58 | 59 | Task AverageAsync(IQueryable collection, Expression> selector); 60 | 61 | Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 62 | 63 | Task AverageAsync(IQueryable collection, Expression> selector); 64 | 65 | Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 66 | 67 | Task AverageAsync(IQueryable collection, Expression> selector); 68 | 69 | Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 70 | 71 | Task AverageAsync(IQueryable collection, Expression> selector); 72 | 73 | Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 74 | 75 | Task AverageAsync(IQueryable collection, Expression> selector); 76 | 77 | Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 78 | 79 | Task AverageAsync(IQueryable collection, Expression> selector); 80 | 81 | Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 82 | 83 | Task AverageAsync(IQueryable collection, Expression> selector); 84 | 85 | Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 86 | 87 | Task AverageAsync(IQueryable collection, Expression> selector); 88 | 89 | Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 90 | } 91 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/IDataContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | 5 | namespace CommandQueryExample.Common 6 | { 7 | public interface IDataContext : IDisposable 8 | { 9 | bool IsDisposed { get; } 10 | 11 | int SaveChanges(); 12 | 13 | Task SaveChangesAsync(); 14 | 15 | Task SaveChangesAsync(CancellationToken cancellationToken); 16 | } 17 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/IDbSetExtensionsUtil.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace CommandQueryExample.Common 7 | { 8 | public interface IDbSetExtensionsUtil : IStartupTask 9 | { 10 | T Add(IQueryable collection, T entity) where T : class; 11 | 12 | IEnumerable AddRange(IQueryable collection, IEnumerable entities) where T : class; 13 | 14 | T Attach(IQueryable collection, T entity) where T : class; 15 | 16 | T Create(IQueryable collection) where T : class; 17 | 18 | TDerivedType Create(IQueryable collection) where T : class where TDerivedType : class, T; 19 | 20 | T Find(IQueryable collection, params object[] keyValues) where T : class; 21 | 22 | Task FindAsync(IQueryable collection, params object[] keyValues) where T : class; 23 | 24 | Task FindAsync(IQueryable collection, CancellationToken cancellationToken, params object[] keyValues) where T : class; 25 | 26 | T Remove(IQueryable collection, T entity) where T : class; 27 | 28 | IEnumerable RemoveRange(IQueryable collection, IEnumerable entities) where T : class; 29 | 30 | IEnumerable SqlQuery(IQueryable collection, string sql, params object[] parameters) where T : class; 31 | } 32 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/IDispatcher.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | 4 | namespace CommandQueryExample.Common 5 | { 6 | public interface IDispatcher 7 | { 8 | IEnumerable Get(BaseQuery query) where T : class; 9 | 10 | Task> GetAsync(BaseAsyncQuery query) where T : class; 11 | 12 | T GetScalar(BaseScalarQuery query) where T : class; 13 | 14 | Task GetScalarAsync(BaseAsyncScalarQuery query) where T : class; 15 | 16 | void QueueCommand(BaseCommand command) where T : class; 17 | } 18 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/IQueryExtensionsUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace CommandQueryExample.Common 9 | { 10 | public interface IQueryExtensionsUtil : IStartupTask 11 | { 12 | Task AllAsync(IQueryable collection, Expression> selector) where T : class; 13 | 14 | Task AllAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class; 15 | 16 | Task AnyAsync(IQueryable collection) where T : class; 17 | 18 | Task AnyAsync(IQueryable collection, CancellationToken cancellationToken) where T : class; 19 | 20 | Task AnyAsync(IQueryable collection, Expression> selector) where T : class; 21 | 22 | Task AnyAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class; 23 | 24 | IQueryable AsNoTracking(IQueryable collection) where T : class; 25 | 26 | Task ContainsAsync(IQueryable collection, T item) where T : class; 27 | 28 | Task ContainsAsync(IQueryable collection, T item, CancellationToken cancellationToken) where T : class; 29 | 30 | Task CountAsync(IQueryable collection) where T : class; 31 | 32 | Task CountAsync(IQueryable collection, CancellationToken cancellationToken) where T : class; 33 | 34 | Task CountAsync(IQueryable collection, Expression> selector) where T : class; 35 | 36 | Task CountAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class; 37 | 38 | Task FirstAsync(IQueryable collection) where T : class; 39 | 40 | Task FirstAsync(IQueryable collection, CancellationToken cancellationToken) where T : class; 41 | 42 | Task FirstAsync(IQueryable collection, Expression> selector) where T : class; 43 | 44 | Task FirstAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class; 45 | 46 | Task FirstOrDefaultAsync(IQueryable collection) where T : class; 47 | 48 | Task FirstOrDefaultAsync(IQueryable collection, CancellationToken cancellationToken) where T : class; 49 | 50 | Task FirstOrDefaultAsync(IQueryable collection, Expression> selector) where T : class; 51 | 52 | Task FirstOrDefaultAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class; 53 | 54 | Task ForEachAsync(IQueryable collection, Action action) where T : class; 55 | 56 | Task ForEachAsync(IQueryable collection, Action action, CancellationToken cancellationToken) where T : class; 57 | 58 | IQueryable Include(IQueryable collection, string path) where T : class; 59 | 60 | IQueryable Include(IQueryable collection, Expression> path) where T : class; 61 | 62 | void Load(IQueryable collection) where T : class; 63 | 64 | Task LoadAsync(IQueryable collection) where T : class; 65 | 66 | Task LoadAsync(IQueryable collection, CancellationToken cancellationToken) where T : class; 67 | 68 | Task LongCountAsync(IQueryable collection) where T : class; 69 | 70 | Task LongCountAsync(IQueryable collection, CancellationToken cancellationToken) where T : class; 71 | 72 | Task LongCountAsync(IQueryable collection, Expression> selector) where T : class; 73 | 74 | Task LongCountAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class; 75 | 76 | Task MaxAsync(IQueryable collection) where T : class; 77 | 78 | Task MaxAsync(IQueryable collection, CancellationToken cancellationToken) where T : class; 79 | 80 | Task MaxAsync(IQueryable collection, Expression> selector) where T : class; 81 | 82 | Task MaxAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class; 83 | 84 | Task MinAsync(IQueryable collection) where T : class; 85 | 86 | Task MinAsync(IQueryable collection, CancellationToken cancellationToken) where T : class; 87 | 88 | Task MinAsync(IQueryable collection, Expression> selector) where T : class; 89 | 90 | Task MinAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class; 91 | 92 | Task SingleAsync(IQueryable collection) where T : class; 93 | 94 | Task SingleAsync(IQueryable collection, CancellationToken cancellationToken) where T : class; 95 | 96 | Task SingleAsync(IQueryable collection, Expression> selector) where T : class; 97 | 98 | Task SingleAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class; 99 | 100 | Task SingleOrDefaultAsync(IQueryable collection) where T : class; 101 | 102 | Task SingleOrDefaultAsync(IQueryable collection, CancellationToken cancellationToken) where T : class; 103 | 104 | Task SingleOrDefaultAsync(IQueryable collection, Expression> selector) where T : class; 105 | 106 | Task SingleOrDefaultAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class; 107 | 108 | IQueryable Skip(IQueryable collection, Expression> countAccessor) where T : class; 109 | 110 | IQueryable Take(IQueryable collection, Expression> countAccessor) where T : class; 111 | 112 | Task ToArrayAsync(IQueryable collection) where T : class; 113 | 114 | Task ToArrayAsync(IQueryable collection, CancellationToken cancellationToken) where T : class; 115 | 116 | Task> ToDictionaryAsync(IQueryable collection, Func keySelector) where T : class; 117 | 118 | Task> ToDictionaryAsync(IQueryable collection, Func keySelector, CancellationToken cancellationToken) where T : class; 119 | 120 | Task> ToDictionaryAsync(IQueryable collection, Func keySelector, IEqualityComparer comparer ) where T : class; 121 | 122 | Task> ToDictionaryAsync(IQueryable collection, Func keySelector, IEqualityComparer comparer , CancellationToken cancellationToken) where T : class; 123 | 124 | Task> ToDictionaryAsync(IQueryable collection, Func keySelector, Func elementSelector) where T : class; 125 | 126 | Task> ToDictionaryAsync(IQueryable collection, Func keySelector, Func elementSelector, CancellationToken cancellationToken) where T : class; 127 | 128 | Task> ToDictionaryAsync(IQueryable collection, Func keySelector, Func elementSelector, IEqualityComparer comparer ) where T : class; 129 | 130 | Task> ToDictionaryAsync(IQueryable collection, Func keySelector, Func elementSelector, IEqualityComparer comparer , CancellationToken cancellationToken) where T : class; 131 | 132 | Task> ToListAsync(IQueryable collection) where T : class; 133 | 134 | Task> ToListAsync(IQueryable collection, CancellationToken cancellationToken) where T : class; 135 | } 136 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/IStartupTask.cs: -------------------------------------------------------------------------------- 1 | namespace CommandQueryExample.Common 2 | { 3 | /// 4 | /// Implement this interface to execute code that must fire at application startup but after the IoC container is 5 | /// configured. 6 | /// Execution order is non-determinant. 7 | /// 8 | public interface IStartupTask 9 | { 10 | void OnStartup(); 11 | } 12 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/ISumAsyncExtensionsUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace CommandQueryExample.Common 8 | { 9 | public interface ISumAsyncExtensionsUtil : IStartupTask 10 | { 11 | Task SumAsync(IQueryable collection); 12 | 13 | Task SumAsync(IQueryable collection, CancellationToken cancellationToken); 14 | 15 | Task SumAsync(IQueryable collection); 16 | 17 | Task SumAsync(IQueryable collection, CancellationToken cancellationToken); 18 | 19 | Task SumAsync(IQueryable collection); 20 | 21 | Task SumAsync(IQueryable collection, CancellationToken cancellationToken); 22 | 23 | Task SumAsync(IQueryable collection); 24 | 25 | Task SumAsync(IQueryable collection, CancellationToken cancellationToken); 26 | 27 | Task SumAsync(IQueryable collection); 28 | 29 | Task SumAsync(IQueryable collection, CancellationToken cancellationToken); 30 | 31 | Task SumAsync(IQueryable collection); 32 | 33 | Task SumAsync(IQueryable collection, CancellationToken cancellationToken); 34 | 35 | Task SumAsync(IQueryable collection); 36 | 37 | Task SumAsync(IQueryable collection, CancellationToken cancellationToken); 38 | 39 | Task SumAsync(IQueryable collection); 40 | 41 | Task SumAsync(IQueryable collection, CancellationToken cancellationToken); 42 | 43 | Task SumAsync(IQueryable collection); 44 | 45 | Task SumAsync(IQueryable collection, CancellationToken cancellationToken); 46 | 47 | Task SumAsync(IQueryable collection); 48 | 49 | Task SumAsync(IQueryable collection, CancellationToken cancellationToken); 50 | 51 | Task SumAsync(IQueryable collection, Expression> selector); 52 | 53 | Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 54 | 55 | Task SumAsync(IQueryable collection, Expression> selector); 56 | 57 | Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 58 | 59 | Task SumAsync(IQueryable collection, Expression> selector); 60 | 61 | Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 62 | 63 | Task SumAsync(IQueryable collection, Expression> selector); 64 | 65 | Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 66 | 67 | Task SumAsync(IQueryable collection, Expression> selector); 68 | 69 | Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 70 | 71 | Task SumAsync(IQueryable collection, Expression> selector); 72 | 73 | Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 74 | 75 | Task SumAsync(IQueryable collection, Expression> selector); 76 | 77 | Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 78 | 79 | Task SumAsync(IQueryable collection, Expression> selector); 80 | 81 | Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 82 | 83 | Task SumAsync(IQueryable collection, Expression> selector); 84 | 85 | Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 86 | 87 | Task SumAsync(IQueryable collection, Expression> selector); 88 | 89 | Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken); 90 | } 91 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Logger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using log4net; 6 | using log4net.Appender; 7 | using log4net.Config; 8 | 9 | namespace CommandQueryExample.Common 10 | { 11 | public class Logger : IStartupTask 12 | { 13 | const string ConfigFileName = "Log4Net.config"; 14 | 15 | static bool _logInitialized; 16 | static readonly Dictionary Loggers = new Dictionary(); 17 | 18 | public static Action Debug = (source, message) => { }; 19 | public static Action Error = (source, message) => { }; 20 | public static Action Fatal = (source, message) => { }; 21 | public static Action Info = (source, message) => { }; 22 | public static Action Warn = (source, message) => { }; 23 | public static Action Trace = message => { }; 24 | 25 | ILog _traceLogger; 26 | 27 | ILog TraceLogger { get { return _traceLogger ?? (_traceLogger = LogManager.GetLogger("Trace")); } } 28 | 29 | public void OnStartup() 30 | { 31 | Debug = (source, message) => GetLogger(GetSourceType(source)).Debug(message); 32 | Error = (source, message) => GetLogger(GetSourceType(source)).Error(message); 33 | Fatal = (source, message) => GetLogger(GetSourceType(source)).Fatal(message); 34 | Info = (source, message) => GetLogger(GetSourceType(source)).Info(message); 35 | Warn = (source, message) => GetLogger(GetSourceType(source)).Warn(message); 36 | Trace = message => TraceLogger.Info(message); 37 | } 38 | 39 | static Type GetSourceType(object source) 40 | { 41 | var sourceType = source.GetType(); 42 | if (sourceType == typeof (Type)) return source as Type; 43 | return sourceType; 44 | } 45 | 46 | static ILog GetLogger(Type source) 47 | { 48 | EnsureInitialized(); 49 | 50 | if (Loggers.ContainsKey(source)) return Loggers[source]; 51 | 52 | lock (Loggers) 53 | { 54 | if (!Loggers.ContainsKey(source)) Loggers.Add(source, LogManager.GetLogger(source)); 55 | } 56 | 57 | return Loggers[source]; 58 | } 59 | 60 | static void EnsureInitialized() 61 | { 62 | if (_logInitialized) return; 63 | 64 | Initialize(); 65 | _logInitialized = true; 66 | } 67 | 68 | static void Initialize() 69 | { 70 | XmlConfigurator.ConfigureAndWatch(new FileInfo(GetConfigFilePath())); 71 | } 72 | 73 | static string GetConfigFilePath() 74 | { 75 | var basePath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; 76 | var configPath = Path.Combine(basePath, ConfigFileName); 77 | 78 | if (File.Exists(configPath)) return configPath; 79 | 80 | configPath = Path.Combine(basePath, "bin"); 81 | configPath = Path.Combine(configPath, ConfigFileName); 82 | 83 | if (!File.Exists(configPath)) configPath = Path.Combine(basePath, @"..\" + ConfigFileName); 84 | 85 | return configPath; 86 | } 87 | 88 | public static void LogCleanUp() 89 | { 90 | var repo = GetLogger(GetSourceType("Debug")).Logger.Repository; 91 | 92 | if (repo == null) 93 | throw new NotSupportedException("Log4Net has not been configured yet."); 94 | 95 | var rollingFileAppenders = repo.GetAppenders().Where(x => x.GetType() == typeof (RollingFileAppender)).ToList(); 96 | foreach (var appender in rollingFileAppenders) 97 | CleanUp(appender); 98 | } 99 | 100 | static void CleanUp(IAppender app) 101 | { 102 | try 103 | { 104 | if (app == null) return; 105 | var appender = app as RollingFileAppender; 106 | 107 | if (appender == null) return; 108 | if (appender.MaxSizeRollBackups <= 0) return; 109 | 110 | var directory = Path.GetDirectoryName(appender.File); 111 | var fileName = Path.GetFileName(appender.File); 112 | var filePrefix = Path.GetFileName(appender.File); 113 | if (filePrefix != null) 114 | { 115 | filePrefix = filePrefix.Substring(0, filePrefix.IndexOf(".", StringComparison.Ordinal)); 116 | filePrefix = filePrefix.Substring(0, filePrefix.IndexOfAny("0123456789".ToCharArray())); 117 | } 118 | 119 | var purgeDate = DateTime.Now.AddDays(appender.MaxSizeRollBackups*(-1)); 120 | CleanUp(directory, filePrefix, purgeDate, fileName); 121 | } 122 | catch 123 | { 124 | throw new Exception("Invalid Log Type"); 125 | } 126 | } 127 | 128 | static void CleanUp(string logDirectory, string logPrefix, DateTime date, string fileName) 129 | { 130 | if (string.IsNullOrEmpty(logDirectory)) 131 | throw new ArgumentException("logDirectory is missing"); 132 | 133 | if (string.IsNullOrEmpty(logPrefix)) 134 | throw new ArgumentException("logPrefix is missing"); 135 | 136 | var dirInfo = new DirectoryInfo(logDirectory); 137 | if (!dirInfo.Exists) 138 | return; 139 | 140 | var fileInfos = dirInfo.GetFiles(string.Format("{0}*.*", logPrefix)); 141 | if (fileInfos.Length == 0) 142 | return; 143 | 144 | foreach (var info in fileInfos.Where(info => info.Name.ToUpper().StartsWith(logPrefix.ToUpper()) 145 | && String.Compare(info.Name, fileName, StringComparison.InvariantCultureIgnoreCase) != 0 && info.CreationTime < date)) 146 | info.Delete(); 147 | } 148 | } 149 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | 8 | [assembly: AssemblyTitle("CommandQueryExample.Common")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CommandQueryExample.Common")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | 25 | [assembly: Guid("b22a2f0a-c091-45e2-846e-a60b9703a663")] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Build and Revision Numbers 35 | // by using the '*' as shown below: 36 | // [assembly: AssemblyVersion("1.0.*")] 37 | 38 | [assembly: AssemblyVersion("1.0.0.0")] 39 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardCommands/AddCommand.cs: -------------------------------------------------------------------------------- 1 | using CommandQueryExample.Common.Extensions; 2 | 3 | namespace CommandQueryExample.Common.StandardCommands 4 | { 5 | public class AddCommand : BaseCommand where T : class 6 | { 7 | public AddCommand(T item) 8 | { 9 | Action = s => 10 | { 11 | s.Add(item); 12 | MarkAsAdded(item); 13 | }; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardCommands/AddRangeCommand.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CommandQueryExample.Common.Extensions; 3 | 4 | namespace CommandQueryExample.Common.StandardCommands 5 | { 6 | public class AddRangeCommand : BaseCommand where T : class 7 | { 8 | public AddRangeCommand(IEnumerable items) 9 | { 10 | Action = s => 11 | { 12 | s.AddRange(items); 13 | foreach (var item in items) 14 | MarkAsAdded(item); 15 | }; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardCommands/RemoveCommand.cs: -------------------------------------------------------------------------------- 1 | using CommandQueryExample.Common.Extensions; 2 | 3 | namespace CommandQueryExample.Common.StandardCommands 4 | { 5 | public class RemoveCommand : BaseCommand where T : class 6 | { 7 | public RemoveCommand(T item) 8 | { 9 | Action = s => 10 | { 11 | s.Remove(item); 12 | MarkAsDeleted(item); 13 | }; 14 | } 15 | 16 | public RemoveCommand(params object[] keyValues) 17 | { 18 | Action = s => 19 | { 20 | var item = s.Find(keyValues); 21 | Verify.NotNull(item, "item"); 22 | s.Remove(item); 23 | MarkAsDeleted(item); 24 | }; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardCommands/RemoveRangeCommand.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CommandQueryExample.Common.Extensions; 3 | 4 | namespace CommandQueryExample.Common.StandardCommands 5 | { 6 | public class RemoveRangeCommand : BaseCommand where T : class 7 | { 8 | public RemoveRangeCommand(IEnumerable items) 9 | { 10 | Action = s => 11 | { 12 | s.RemoveRange(items); 13 | foreach (var item in items) 14 | MarkAsDeleted(item); 15 | }; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardCommands/UpdateCommand.cs: -------------------------------------------------------------------------------- 1 | namespace CommandQueryExample.Common.StandardCommands 2 | { 3 | public class UpdateCommand : BaseCommand where T : class 4 | { 5 | public UpdateCommand(T item) 6 | { 7 | Action = s => MarkAsModified(item); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardCommands/UpdateRangeCommand.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CommandQueryExample.Common.StandardCommands 4 | { 5 | public class UpdateRangeCommand : BaseCommand where T : class 6 | { 7 | public UpdateRangeCommand(IEnumerable items) 8 | { 9 | Action = s => 10 | { 11 | foreach (var item in items) 12 | MarkAsModified(item); 13 | }; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/Async/FindAsyncQuery.cs: -------------------------------------------------------------------------------- 1 | using CommandQueryExample.Common.Extensions; 2 | 3 | namespace CommandQueryExample.Common.StandardQueries.Async 4 | { 5 | public class FindAsyncQuery : BaseAsyncScalarQuery where T : class 6 | { 7 | public FindAsyncQuery(params object[] keyValues) 8 | { 9 | Query = s => s.FindAsync(keyValues); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/Async/FirstAsyncQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using CommandQueryExample.Common.Extensions; 4 | 5 | namespace CommandQueryExample.Common.StandardQueries.Async 6 | { 7 | public class FirstAsyncQuery : BaseAsyncScalarQuery where T : class 8 | { 9 | public FirstAsyncQuery(Expression> selector = null) 10 | { 11 | if (selector.IsNull()) 12 | Query = s => s.FirstAsync(); 13 | Query = s => s.FirstAsync(selector); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/Async/FirstOrDefaultAsyncQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using CommandQueryExample.Common.Extensions; 4 | 5 | namespace CommandQueryExample.Common.StandardQueries.Async 6 | { 7 | public class FirstOrDefaultAsyncQuery : BaseAsyncScalarQuery where T : class 8 | { 9 | public FirstOrDefaultAsyncQuery(Expression> selector = null) 10 | { 11 | if (selector.IsNull()) 12 | Query = s => s.FirstOrDefaultAsync(); 13 | Query = s => s.FirstOrDefaultAsync(selector); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/Async/GetAllAsyncQuery.cs: -------------------------------------------------------------------------------- 1 | using CommandQueryExample.Common.Extensions; 2 | 3 | namespace CommandQueryExample.Common.StandardQueries.Async 4 | { 5 | public class GetAllAsyncQuery : BaseAsyncQuery where T : class 6 | { 7 | public GetAllAsyncQuery() 8 | { 9 | Query = s => s.ToListAsync(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/Async/SingleAsyncQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using CommandQueryExample.Common.Extensions; 4 | 5 | namespace CommandQueryExample.Common.StandardQueries.Async 6 | { 7 | public class SingleAsyncQuery : BaseAsyncScalarQuery where T : class 8 | { 9 | public SingleAsyncQuery(Expression> selector) 10 | { 11 | if (selector.IsNull()) 12 | Query = s => s.SingleAsync(); 13 | Query = s => s.SingleAsync(selector); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/Async/SingleOrDefaultAsyncQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using CommandQueryExample.Common.Extensions; 4 | 5 | namespace CommandQueryExample.Common.StandardQueries.Async 6 | { 7 | public class SingleOrDefaultAsyncQuery : BaseAsyncScalarQuery where T : class 8 | { 9 | public SingleOrDefaultAsyncQuery(Expression> selector = null) 10 | { 11 | if (selector.IsNull()) 12 | Query = s => s.SingleOrDefaultAsync(); 13 | Query = s => s.SingleOrDefaultAsync(selector); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/Async/WhereAsyncQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using CommandQueryExample.Common.Extensions; 5 | 6 | namespace CommandQueryExample.Common.StandardQueries.Async 7 | { 8 | public class WhereAsyncQuery : BaseAsyncQuery where T : class 9 | { 10 | public WhereAsyncQuery(Expression> selector) 11 | { 12 | Query = s => s.Where(selector).ToListAsync(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/FindQuery.cs: -------------------------------------------------------------------------------- 1 | using CommandQueryExample.Common.Extensions; 2 | 3 | namespace CommandQueryExample.Common.StandardQueries 4 | { 5 | public class FindQuery : BaseScalarQuery where T : class 6 | { 7 | public FindQuery(params object[] keyValues) 8 | { 9 | Query = s => s.Find(keyValues); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/FirstOrDefaultQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using CommandQueryExample.Common.Extensions; 5 | 6 | namespace CommandQueryExample.Common.StandardQueries 7 | { 8 | public class FirstOrDefaultQuery : BaseScalarQuery where T : class 9 | { 10 | public FirstOrDefaultQuery(Expression> selector = null) 11 | { 12 | if (selector.IsNull()) 13 | { 14 | Query = s => s.FirstOrDefault(); 15 | return; 16 | } 17 | Query = s => s.FirstOrDefault(selector); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/FirstQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using CommandQueryExample.Common.Extensions; 5 | 6 | namespace CommandQueryExample.Common.StandardQueries 7 | { 8 | public class FirstQuery : BaseScalarQuery where T : class 9 | { 10 | public FirstQuery(Expression> selector = null) 11 | { 12 | if (selector.IsNull()) 13 | { 14 | Query = s => s.First(); 15 | return; 16 | } 17 | Query = s => s.First(selector); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/GetAllQuery.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace CommandQueryExample.Common.StandardQueries 4 | { 5 | public class GetAllQuery : BaseQuery where T : class 6 | { 7 | public GetAllQuery() 8 | { 9 | Query = s => s.AsEnumerable(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/SingleOrDefaultQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using CommandQueryExample.Common.Extensions; 5 | 6 | namespace CommandQueryExample.Common.StandardQueries 7 | { 8 | public class SingleOrDefaultQuery : BaseScalarQuery where T : class 9 | { 10 | public SingleOrDefaultQuery(Expression> selector = null) 11 | { 12 | if (selector.IsNull()) 13 | Query = s => s.SingleOrDefault(); 14 | Query = s => s.SingleOrDefault(selector); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/SingleQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using CommandQueryExample.Common.Extensions; 5 | 6 | namespace CommandQueryExample.Common.StandardQueries 7 | { 8 | public class SingleQuery : BaseScalarQuery where T : class 9 | { 10 | public SingleQuery(Expression> selector = null) 11 | { 12 | if (selector.IsNull()) 13 | Query = s => s.Single(); 14 | Query = s => s.Single(selector); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/StandardQueries/WhereQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | 5 | namespace CommandQueryExample.Common.StandardQueries 6 | { 7 | public class WhereQuery : BaseQuery where T : class 8 | { 9 | public WhereQuery(Expression> selector) 10 | { 11 | Query = s => s.Where(selector).ToList(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/Verify.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using CommandQueryExample.Common.Extensions; 6 | 7 | namespace CommandQueryExample.Common 8 | { 9 | /// 10 | /// Adapted from http://kigg.codeplex.com/ 11 | /// 12 | [Serializable] 13 | public class Verify 14 | { 15 | internal Verify() {} 16 | 17 | [DebuggerStepThrough] 18 | public static void NotEmpty(Guid argument, string argumentName) 19 | { 20 | if (argument == Guid.Empty) throw new ArgumentException(argumentName + " cannot be empty guid.", argumentName); 21 | } 22 | 23 | [DebuggerStepThrough] 24 | public static void NotEmpty(string argument, string argumentName) 25 | { 26 | if (string.IsNullOrEmpty((argument ?? string.Empty).Trim())) 27 | throw new ArgumentException(argumentName + " cannot be empty.", argumentName); 28 | } 29 | 30 | [DebuggerStepThrough] 31 | public static void NotEmpty(int argument, string argumentName) 32 | { 33 | if (argument <= 0) throw new ArgumentException(argumentName + " cannot be empty.", argumentName); 34 | } 35 | 36 | [DebuggerStepThrough] 37 | public static void NotEmpty(TimeSpan argument, string argumentName) 38 | { 39 | if (Math.Abs(argument.TotalMilliseconds - 0.0F) == 0) throw new ArgumentException(argumentName + " cannot be empty.", argumentName); 40 | } 41 | 42 | [DebuggerStepThrough] 43 | public static void WithinLength(string argument, int length, string argumentName) 44 | { 45 | if (argument.Trim().Length > length) 46 | throw new ArgumentException(argumentName + " cannot be more than " + length + " characters", argumentName); 47 | } 48 | 49 | [DebuggerStepThrough] 50 | public static void Null(object argument, string argumentName) 51 | { 52 | if (argument != null) throw new ArgumentException(argumentName + " must be null", argumentName); 53 | } 54 | 55 | [DebuggerStepThrough] 56 | public static void NotNull(object argument, string argumentName) 57 | { 58 | if (argument.IsNull()) throw new ArgumentNullException(argumentName); 59 | } 60 | 61 | [DebuggerStepThrough] 62 | public static void PositiveOrZero(int argument, string argumentName) 63 | { 64 | if (argument < 0) throw new ArgumentOutOfRangeException(argumentName); 65 | } 66 | 67 | [DebuggerStepThrough] 68 | public static void Positive(int argument, string argumentName) 69 | { 70 | if (argument <= 0) throw new ArgumentOutOfRangeException(argumentName); 71 | } 72 | 73 | [DebuggerStepThrough] 74 | public static void PositiveOrZero(long argument, string argumentName) 75 | { 76 | if (argument < 0) throw new ArgumentOutOfRangeException(argumentName); 77 | } 78 | 79 | [DebuggerStepThrough] 80 | public static void Positive(long argument, string argumentName) 81 | { 82 | if (argument <= 0) throw new ArgumentOutOfRangeException(argumentName); 83 | } 84 | 85 | [DebuggerStepThrough] 86 | public static void PositiveOrZero(float argument, string argumentName) 87 | { 88 | if (argument < 0) throw new ArgumentOutOfRangeException(argumentName); 89 | } 90 | 91 | [DebuggerStepThrough] 92 | public static void Positive(float argument, string argumentName) 93 | { 94 | if (argument <= 0) throw new ArgumentOutOfRangeException(argumentName); 95 | } 96 | 97 | [DebuggerStepThrough] 98 | public static void PositiveOrZero(decimal argument, string argumentName) 99 | { 100 | if (argument < 0) throw new ArgumentOutOfRangeException(argumentName); 101 | } 102 | 103 | [DebuggerStepThrough] 104 | public static void Positive(decimal argument, string argumentName) 105 | { 106 | if (argument <= 0) throw new ArgumentOutOfRangeException(argumentName); 107 | } 108 | 109 | /* 110 | [DebuggerStepThrough] 111 | public static void ValidDate(DateTime argument, string argumentName) 112 | { 113 | if (!argument.IsValid()) 114 | throw new ArgumentOutOfRangeException(argumentName); 115 | } 116 | 117 | [DebuggerStepThrough] 118 | public static void InFuture(DateTime argument, string argumentName) 119 | { 120 | if (argument < SystemTime.Now()) 121 | throw new ArgumentOutOfRangeException(argumentName); 122 | } 123 | 124 | [DebuggerStepThrough] 125 | public static void InPast(DateTime argument, string argumentName) 126 | { 127 | if (argument > SystemTime.Now()) 128 | throw new ArgumentOutOfRangeException(argumentName); 129 | } 130 | */ 131 | 132 | [DebuggerStepThrough] 133 | public static void PositiveOrZero(TimeSpan argument, string argumentName) 134 | { 135 | if (argument < TimeSpan.Zero) throw new ArgumentOutOfRangeException(argumentName); 136 | } 137 | 138 | [DebuggerStepThrough] 139 | public static void Positive(TimeSpan argument, string argumentName) 140 | { 141 | if (argument <= TimeSpan.Zero) throw new ArgumentOutOfRangeException(argumentName); 142 | } 143 | 144 | [DebuggerStepThrough] 145 | public static void NotEmpty(IEnumerable argument, string argumentName) 146 | { 147 | NotNull(argument, argumentName); 148 | 149 | if (!argument.Any()) throw new ArgumentException("Enumerable cannot be empty.", argumentName); 150 | } 151 | 152 | [DebuggerStepThrough] 153 | public static void InRange(int argument, int min, int max, string argumentName) 154 | { 155 | if ((argument < min) || (argument > max)) 156 | throw new ArgumentOutOfRangeException(argumentName, argumentName + "must be between " + min + "-" + max + "."); 157 | } 158 | 159 | public static void AreEqual(T expected, T actual, string argumentName) 160 | { 161 | if (!EqualityComparer.Default.Equals(expected, actual)) 162 | { 163 | throw new ArgumentOutOfRangeException(argumentName, 164 | argumentName + " must be " + expected + ", but was " + actual + "."); 165 | } 166 | } 167 | 168 | public static void True(bool actual, string argumentName) 169 | { 170 | AreEqual(true, actual, argumentName); 171 | } 172 | 173 | public static void False(bool actual, string argumentName) 174 | { 175 | AreEqual(false, actual, argumentName); 176 | } 177 | 178 | public static void AreNotEqual(T expected, T actual, string argumentName) 179 | { 180 | if (EqualityComparer.Default.Equals(expected, actual)) 181 | throw new ArgumentOutOfRangeException(argumentName, argumentName + " must not be equal to " + expected + "."); 182 | } 183 | 184 | /* 185 | [DebuggerStepThrough] 186 | public static void NotInvalidEmail(string argument, string argumentName) 187 | { 188 | NotEmpty(argument, argumentName); 189 | 190 | if (!argument.IsEmail()) 191 | { 192 | throw new ArgumentException("\"{0}\" is not a valid email address.".FormatWith(argumentName), argumentName); 193 | } 194 | } 195 | 196 | 197 | [DebuggerStepThrough] 198 | public static void NotInvalidWebUrl(string argument, string argumentName) 199 | { 200 | NotEmpty(argument, argumentName); 201 | 202 | if (!argument.IsWebUrl()) 203 | { 204 | throw new ArgumentException("\"{0}\" is not a valid web url.".FormatWith(argumentName), argumentName); 205 | } 206 | } 207 | */ 208 | 209 | [DebuggerStepThrough] 210 | public static void ValidID(int? id, string argumentName) 211 | { 212 | NotNull(id, argumentName); 213 | Positive(id.Value, argumentName); 214 | } 215 | } 216 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Common/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/AverageAsyncExtensionsUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using CommandQueryExample.Common; 8 | using CommandQueryExample.Common.Extensions; 9 | 10 | namespace CommandQueryExample.Data 11 | { 12 | // ReSharper disable InvokeAsExtensionMethod 13 | public class AverageAsyncExtensionsUtil : IAverageAsyncExtensionsUtil 14 | { 15 | public async Task AverageAsync(IQueryable collection) 16 | { 17 | return await QueryableExtensions.AverageAsync(collection); 18 | } 19 | 20 | public async Task AverageAsync(IQueryable collection, CancellationToken cancellationToken) 21 | { 22 | return await QueryableExtensions.AverageAsync(collection, cancellationToken); 23 | } 24 | 25 | public async Task AverageAsync(IQueryable collection) 26 | { 27 | return await QueryableExtensions.AverageAsync(collection); 28 | } 29 | 30 | public async Task AverageAsync(IQueryable collection, CancellationToken cancellationToken) 31 | { 32 | return await QueryableExtensions.AverageAsync(collection, cancellationToken); 33 | } 34 | 35 | public async Task AverageAsync(IQueryable collection) 36 | { 37 | return await QueryableExtensions.AverageAsync(collection); 38 | } 39 | 40 | public async Task AverageAsync(IQueryable collection, CancellationToken cancellationToken) 41 | { 42 | return await QueryableExtensions.AverageAsync(collection, cancellationToken); 43 | } 44 | 45 | public async Task AverageAsync(IQueryable collection) 46 | { 47 | return await QueryableExtensions.AverageAsync(collection); 48 | } 49 | 50 | public async Task AverageAsync(IQueryable collection, CancellationToken cancellationToken) 51 | { 52 | return await QueryableExtensions.AverageAsync(collection, cancellationToken); 53 | } 54 | 55 | public async Task AverageAsync(IQueryable collection) 56 | { 57 | return await QueryableExtensions.AverageAsync(collection); 58 | } 59 | 60 | public async Task AverageAsync(IQueryable collection, CancellationToken cancellationToken) 61 | { 62 | return await QueryableExtensions.AverageAsync(collection, cancellationToken); 63 | } 64 | 65 | public async Task AverageAsync(IQueryable collection) 66 | { 67 | return await QueryableExtensions.AverageAsync(collection); 68 | } 69 | 70 | public async Task AverageAsync(IQueryable collection, CancellationToken cancellationToken) 71 | { 72 | return await QueryableExtensions.AverageAsync(collection, cancellationToken); 73 | } 74 | 75 | public async Task AverageAsync(IQueryable collection) 76 | { 77 | return await QueryableExtensions.AverageAsync(collection); 78 | } 79 | 80 | public async Task AverageAsync(IQueryable collection, CancellationToken cancellationToken) 81 | { 82 | return await QueryableExtensions.AverageAsync(collection, cancellationToken); 83 | } 84 | 85 | public async Task AverageAsync(IQueryable collection) 86 | { 87 | return await QueryableExtensions.AverageAsync(collection); 88 | } 89 | 90 | public async Task AverageAsync(IQueryable collection, CancellationToken cancellationToken) 91 | { 92 | return await QueryableExtensions.AverageAsync(collection, cancellationToken); 93 | } 94 | 95 | public async Task AverageAsync(IQueryable collection) 96 | { 97 | return await QueryableExtensions.AverageAsync(collection); 98 | } 99 | 100 | public async Task AverageAsync(IQueryable collection, CancellationToken cancellationToken) 101 | { 102 | return await QueryableExtensions.AverageAsync(collection, cancellationToken); 103 | } 104 | 105 | public async Task AverageAsync(IQueryable collection) 106 | { 107 | return await QueryableExtensions.AverageAsync(collection); 108 | } 109 | 110 | public async Task AverageAsync(IQueryable collection, CancellationToken cancellationToken) 111 | { 112 | return await QueryableExtensions.AverageAsync(collection, cancellationToken); 113 | } 114 | 115 | public async Task AverageAsync(IQueryable collection, Expression> selector) 116 | { 117 | return await QueryableExtensions.AverageAsync(collection, selector); 118 | } 119 | 120 | public async Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 121 | { 122 | return await QueryableExtensions.AverageAsync(collection, selector, cancellationToken); 123 | } 124 | 125 | public async Task AverageAsync(IQueryable collection, Expression> selector) 126 | { 127 | return await QueryableExtensions.AverageAsync(collection, selector); 128 | } 129 | 130 | public async Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 131 | { 132 | return await QueryableExtensions.AverageAsync(collection, selector, cancellationToken); 133 | } 134 | 135 | public async Task AverageAsync(IQueryable collection, Expression> selector) 136 | { 137 | return await QueryableExtensions.AverageAsync(collection, selector); 138 | } 139 | 140 | public async Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 141 | { 142 | return await QueryableExtensions.AverageAsync(collection, selector, cancellationToken); 143 | } 144 | 145 | public async Task AverageAsync(IQueryable collection, Expression> selector) 146 | { 147 | return await QueryableExtensions.AverageAsync(collection, selector); 148 | } 149 | 150 | public async Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 151 | { 152 | return await QueryableExtensions.AverageAsync(collection, selector, cancellationToken); 153 | } 154 | 155 | public async Task AverageAsync(IQueryable collection, Expression> selector) 156 | { 157 | return await QueryableExtensions.AverageAsync(collection, selector); 158 | } 159 | 160 | public async Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 161 | { 162 | return await QueryableExtensions.AverageAsync(collection, selector, cancellationToken); 163 | } 164 | 165 | public async Task AverageAsync(IQueryable collection, Expression> selector) 166 | { 167 | return await QueryableExtensions.AverageAsync(collection, selector); 168 | } 169 | 170 | public async Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 171 | { 172 | return await QueryableExtensions.AverageAsync(collection, selector, cancellationToken); 173 | } 174 | 175 | public async Task AverageAsync(IQueryable collection, Expression> selector) 176 | { 177 | return await QueryableExtensions.AverageAsync(collection, selector); 178 | } 179 | 180 | public async Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 181 | { 182 | return await QueryableExtensions.AverageAsync(collection, selector, cancellationToken); 183 | } 184 | 185 | public async Task AverageAsync(IQueryable collection, Expression> selector) 186 | { 187 | return await QueryableExtensions.AverageAsync(collection, selector); 188 | } 189 | 190 | public async Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 191 | { 192 | return await QueryableExtensions.AverageAsync(collection, selector, cancellationToken); 193 | } 194 | 195 | public async Task AverageAsync(IQueryable collection, Expression> selector) 196 | { 197 | return await QueryableExtensions.AverageAsync(collection, selector); 198 | } 199 | 200 | public async Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 201 | { 202 | return await QueryableExtensions.AverageAsync(collection, selector, cancellationToken); 203 | } 204 | 205 | public async Task AverageAsync(IQueryable collection, Expression> selector) 206 | { 207 | return await QueryableExtensions.AverageAsync(collection, selector); 208 | } 209 | 210 | public async Task AverageAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 211 | { 212 | return await QueryableExtensions.AverageAsync(collection, selector, cancellationToken); 213 | } 214 | 215 | public void OnStartup() 216 | { 217 | AverageAsyncExtensions.Util = this; 218 | } 219 | } 220 | // ReSharper restore InvokeAsExtensionMethod 221 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/CommandQueryExample.Data.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E1E7F9EA-040C-405E-8F98-8E40AB6B6857} 8 | Library 9 | Properties 10 | CommandQueryExample.Data 11 | CommandQueryExample.Data 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\EntityFramework.6.1.2\lib\net45\EntityFramework.dll 35 | 36 | 37 | ..\packages\EntityFramework.6.1.2\lib\net45\EntityFramework.SqlServer.dll 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | {91D84F63-79B8-4DC5-A822-EEA3E65C26A4} 67 | CommandQueryExample.Common 68 | 69 | 70 | {38497722-422D-40CC-B841-279AEF0F7543} 71 | CommandQuerySample.Domain 72 | 73 | 74 | 75 | 82 | -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/ContextInitializer.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | using CommandQuerySample.Domain; 3 | 4 | namespace CommandQueryExample.Data 5 | { 6 | public class ContextInitializer : DropCreateDatabaseAlways 7 | { 8 | protected override void Seed(SampleContext context) 9 | { 10 | context.People.Add(new Person {FirstName = "Alan", LastName = "Stevens"}); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/DataContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using CommandQueryExample.Common; 6 | using CommandQueryExample.Common.Extensions; 7 | 8 | namespace CommandQueryExample.Data 9 | { 10 | public class DataContext : DisposableBase, IDataContext 11 | { 12 | public DataContext(DbContext context, bool useTransaction = false, bool disposeDbContext = true) 13 | { 14 | _disposeDbContext = disposeDbContext; 15 | _context = new WeakReference(context); 16 | if (useTransaction) _transaction = new WeakReference(context.Database.BeginTransaction()); 17 | } 18 | 19 | readonly WeakReference _context; 20 | readonly bool _disposeDbContext; 21 | readonly WeakReference _transaction; 22 | 23 | public DbContext Context { get { return RetrieveValidContext(); } } 24 | 25 | public int SaveChanges() 26 | { 27 | return Context.SaveChanges(); 28 | } 29 | 30 | public async Task SaveChangesAsync() 31 | { 32 | return await Context.SaveChangesAsync(); 33 | } 34 | 35 | public async Task SaveChangesAsync(CancellationToken cancellationToken) 36 | { 37 | return await Context.SaveChangesAsync(cancellationToken); 38 | } 39 | 40 | protected override void OnDisposing(bool disposing) 41 | { 42 | if (!disposing) return; 43 | 44 | var dbContext = RetrieveValidContext(); 45 | 46 | DbContextTransaction transaction = null; 47 | 48 | if (_transaction.IsNotNull()) 49 | _transaction.TryGetTarget(out transaction); 50 | 51 | if (transaction.IsNull()) 52 | { 53 | if (_disposeDbContext) dbContext.Dispose(); 54 | return; 55 | } 56 | 57 | try 58 | { 59 | transaction.Commit(); 60 | } 61 | catch 62 | { 63 | transaction.Rollback(); 64 | throw; 65 | } 66 | finally 67 | { 68 | transaction.Dispose(); 69 | if (_disposeDbContext) dbContext.Dispose(); 70 | } 71 | } 72 | 73 | DbContext RetrieveValidContext() 74 | { 75 | if (IsDisposed && _disposeDbContext) throw new ObjectDisposedException("DbContext has been disposed."); 76 | if (IsDisposed) throw new ObjectDisposedException("DataContext has been disposed."); 77 | if (_context.IsNull()) throw new NullReferenceException("DbContext is null."); 78 | DbContext dbContext; 79 | _context.TryGetTarget(out dbContext); 80 | if (dbContext.IsNull()) throw new NullReferenceException("DbContext is null."); 81 | return dbContext; 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/DataContextFactoryStartupTask.cs: -------------------------------------------------------------------------------- 1 | using CommandQueryExample.Common; 2 | 3 | namespace CommandQueryExample.Data 4 | { 5 | public class DataContextFactoryStartupTask : IStartupTask 6 | { 7 | public void OnStartup() 8 | { 9 | DataContextFactory.DataContextInitializer = useTransaction => new DataContext(new SampleContext(), useTransaction); 10 | 11 | // If you use your DI container to manage your DbContext lifecycle, 12 | // you can do something like this to prevent the DataContextFactory 13 | // from disposing your DbContext. 14 | //DataContextFactory.DataContextInitializer = useTransaction => 15 | //{ 16 | // var sampleContext = ServiceLocator.Current.GetInstance(); 17 | // return new DataContext(sampleContext, useTransaction, false); 18 | //}; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/DbSetExtensionsUtil.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Entity; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using CommandQueryExample.Common; 7 | using CommandQueryExample.Common.Extensions; 8 | 9 | namespace CommandQueryExample.Data 10 | { 11 | public class DbSetExtensionsUtil : IDbSetExtensionsUtil 12 | { 13 | public T Add(IQueryable collection, T entity) where T : class 14 | { 15 | return GetSet(collection).Add(entity); 16 | } 17 | 18 | public IEnumerable AddRange(IQueryable collection, IEnumerable entities) where T : class 19 | { 20 | return GetSet(collection).AddRange(entities); 21 | } 22 | 23 | public T Attach(IQueryable collection, T entity) where T : class 24 | { 25 | return GetSet(collection).Attach(entity); 26 | } 27 | 28 | public T Create(IQueryable collection) where T : class 29 | { 30 | return GetSet(collection).Create(); 31 | } 32 | 33 | public TDerivedType Create(IQueryable collection) where T : class where TDerivedType : class, T 34 | { 35 | return GetSet(collection).Create(); 36 | } 37 | 38 | public T Find(IQueryable collection, params object[] keyValues) where T : class 39 | { 40 | return GetSet(collection).Find(keyValues); 41 | } 42 | 43 | public async Task FindAsync(IQueryable collection, params object[] keyValues) where T : class 44 | { 45 | return await GetSet(collection).FindAsync(keyValues); 46 | } 47 | 48 | public async Task FindAsync(IQueryable collection, CancellationToken cancellationToken, params object[] keyValues) where T : class 49 | { 50 | return await GetSet(collection).FindAsync(cancellationToken, keyValues); 51 | } 52 | 53 | public T Remove(IQueryable collection, T entity) where T : class 54 | { 55 | return GetSet(collection).Remove(entity); 56 | } 57 | 58 | public IEnumerable RemoveRange(IQueryable collection, IEnumerable entities) where T : class 59 | { 60 | return GetSet(collection).RemoveRange(entities); 61 | } 62 | 63 | public IEnumerable SqlQuery(IQueryable collection, string sql, params object[] parameters) where T : class 64 | { 65 | return GetSet(collection).SqlQuery(sql, parameters); 66 | } 67 | 68 | public void OnStartup() 69 | { 70 | DbSetExtensions.Util = this; 71 | } 72 | 73 | static DbSet GetSet(IEnumerable collection) where T : class 74 | { 75 | var set = collection as DbSet; 76 | Verify.NotNull(set, "set"); 77 | return set; 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/Dispatcher.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Entity; 3 | using System.Data.Entity.Infrastructure; 4 | using System.Threading.Tasks; 5 | using CommandQueryExample.Common; 6 | 7 | namespace CommandQueryExample.Data 8 | { 9 | public class Dispatcher : IDispatcher 10 | { 11 | static DbContext Context 12 | { 13 | get 14 | { 15 | var currentContext = DataContextFactory.CurrentContext; 16 | return ((DataContext) currentContext).Context; 17 | } 18 | } 19 | 20 | public IEnumerable Get(BaseQuery query) where T : class 21 | { 22 | return query.Call(Context.Set()); 23 | } 24 | 25 | public async Task> GetAsync(BaseAsyncQuery query) where T : class 26 | { 27 | return await query.CallAsync(Context.Set()); 28 | } 29 | 30 | public T GetScalar(BaseScalarQuery query) where T : class 31 | { 32 | return query.Call(Context.Set()); 33 | } 34 | 35 | public async Task GetScalarAsync(BaseAsyncScalarQuery query) where T : class 36 | { 37 | return await query.CallAsync(Context.Set()); 38 | } 39 | 40 | public void QueueCommand(BaseCommand command) where T : class 41 | { 42 | command.MarkAsModified = MarkAsModified; 43 | command.MarkAsAdded = MarkAsAdded; 44 | command.MarkAsDeleted = MarkAsDeleted; 45 | 46 | command.Execute(Context.Set()); 47 | 48 | command.MarkAsModified = x => { }; 49 | command.MarkAsAdded = x => { }; 50 | command.MarkAsDeleted = x => { }; 51 | } 52 | 53 | static void MarkAsModified(T entity) where T : class 54 | { 55 | var entry = GetEntry(entity); 56 | AttachIfNeeded(entry); 57 | entry.State = EntityState.Modified; 58 | } 59 | 60 | static void MarkAsAdded(T entity) where T : class 61 | { 62 | var entry = GetEntry(entity); 63 | AttachIfNeeded(entry); 64 | entry.State = EntityState.Added; 65 | } 66 | 67 | static void MarkAsDeleted(T entity) where T : class 68 | { 69 | var entry = GetEntry(entity); 70 | AttachIfNeeded(entry); 71 | entry.State = EntityState.Deleted; 72 | } 73 | 74 | static DbEntityEntry GetEntry(T entity) where T : class 75 | { 76 | return Context.Entry(entity); 77 | } 78 | 79 | static void AttachIfNeeded(DbEntityEntry entry) where T : class 80 | { 81 | if (entry.State == EntityState.Detached) 82 | Context.Set().Attach(entry.Entity); 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | 8 | [assembly: AssemblyTitle("CommandQueryExample.Data")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CommandQueryExample.Data")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | 25 | [assembly: Guid("02709ff7-d176-4005-b3b0-e95dc7b280f0")] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Build and Revision Numbers 35 | // by using the '*' as shown below: 36 | // [assembly: AssemblyVersion("1.0.*")] 37 | 38 | [assembly: AssemblyVersion("1.0.0.0")] 39 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/QueryExtensionsUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using CommandQueryExample.Common; 9 | using CommandQueryExample.Common.Extensions; 10 | 11 | namespace CommandQueryExample.Data 12 | { 13 | // ReSharper disable InvokeAsExtensionMethod 14 | public class QueryExtensionsUtil : IQueryExtensionsUtil 15 | { 16 | public void OnStartup() 17 | { 18 | QueryExtensions.Util = this; 19 | } 20 | 21 | public async Task AllAsync(IQueryable collection, Expression> selector) where T : class 22 | { 23 | return await QueryableExtensions.AllAsync(collection, selector); 24 | } 25 | 26 | public async Task AllAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class 27 | { 28 | return await QueryableExtensions.AllAsync(collection, selector, cancellationToken); 29 | } 30 | 31 | public async Task AnyAsync(IQueryable collection) where T : class 32 | { 33 | return await QueryableExtensions.AnyAsync(collection); 34 | } 35 | 36 | public async Task AnyAsync(IQueryable collection, CancellationToken cancellationToken) where T : class 37 | { 38 | return await QueryableExtensions.AnyAsync(collection, cancellationToken); 39 | } 40 | 41 | public async Task AnyAsync(IQueryable collection, Expression> selector) where T : class 42 | { 43 | return await QueryableExtensions.AnyAsync(collection, selector); 44 | } 45 | 46 | public async Task AnyAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class 47 | { 48 | return await QueryableExtensions.AnyAsync(collection, selector, cancellationToken); 49 | } 50 | 51 | public IQueryable AsNoTracking(IQueryable collection) where T : class 52 | { 53 | return QueryableExtensions.AsNoTracking(collection); 54 | } 55 | 56 | public async Task ContainsAsync(IQueryable collection, T item) where T : class 57 | { 58 | await QueryableExtensions.ContainsAsync(collection, item); 59 | } 60 | 61 | public async Task ContainsAsync(IQueryable collection, T item, CancellationToken cancellationToken) where T : class 62 | { 63 | return await QueryableExtensions.ContainsAsync(collection, item, cancellationToken); 64 | } 65 | 66 | public async Task CountAsync(IQueryable collection) where T : class 67 | { 68 | return await QueryableExtensions.CountAsync(collection); 69 | } 70 | 71 | public async Task CountAsync(IQueryable collection, CancellationToken cancellationToken) where T : class 72 | { 73 | return await QueryableExtensions.CountAsync(collection, cancellationToken); 74 | } 75 | 76 | public async Task CountAsync(IQueryable collection, Expression> selector) where T : class 77 | { 78 | return await QueryableExtensions.CountAsync(collection, selector); 79 | } 80 | 81 | public async Task CountAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class 82 | { 83 | return await QueryableExtensions.CountAsync(collection, selector, cancellationToken); 84 | } 85 | 86 | public async Task FirstAsync(IQueryable collection) where T : class 87 | { 88 | return await QueryableExtensions.FirstAsync(collection); 89 | } 90 | 91 | public async Task FirstAsync(IQueryable collection, CancellationToken cancellationToken) where T : class 92 | { 93 | return await QueryableExtensions.FirstAsync(collection, cancellationToken); 94 | } 95 | 96 | public async Task FirstAsync(IQueryable collection, Expression> selector) where T : class 97 | { 98 | return await QueryableExtensions.FirstAsync(collection, selector); 99 | } 100 | 101 | public async Task FirstAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class 102 | { 103 | return await QueryableExtensions.FirstAsync(collection, selector, cancellationToken); 104 | } 105 | 106 | public async Task FirstOrDefaultAsync(IQueryable collection) where T : class 107 | { 108 | return await QueryableExtensions.FirstOrDefaultAsync(collection); 109 | } 110 | 111 | public async Task FirstOrDefaultAsync(IQueryable collection, CancellationToken cancellationToken) where T : class 112 | { 113 | return await QueryableExtensions.FirstOrDefaultAsync(collection, cancellationToken); 114 | } 115 | 116 | public async Task FirstOrDefaultAsync(IQueryable collection, Expression> selector) where T : class 117 | { 118 | return await QueryableExtensions.FirstOrDefaultAsync(collection, selector); 119 | } 120 | 121 | public async Task FirstOrDefaultAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class 122 | { 123 | return await QueryableExtensions.FirstOrDefaultAsync(collection, selector,cancellationToken); 124 | } 125 | 126 | public async Task ForEachAsync(IQueryable collection, Action action) where T : class 127 | { 128 | await QueryableExtensions.ForEachAsync(collection, action); 129 | } 130 | 131 | public async Task ForEachAsync(IQueryable collection, Action action, CancellationToken cancellationToken) where T : class 132 | { 133 | await QueryableExtensions.ForEachAsync(collection, action, cancellationToken); 134 | } 135 | 136 | public IQueryable Include(IQueryable collection, string path) where T : class 137 | { 138 | return QueryableExtensions.Include(collection, path); 139 | } 140 | 141 | public IQueryable Include(IQueryable collection, Expression> path) where T : class 142 | { 143 | return QueryableExtensions.Include(collection, path); 144 | } 145 | 146 | public void Load(IQueryable collection) where T : class 147 | { 148 | QueryableExtensions.Load(collection); 149 | } 150 | 151 | public async Task LoadAsync(IQueryable collection) where T : class 152 | { 153 | await QueryableExtensions.LoadAsync(collection); 154 | } 155 | 156 | public async Task LoadAsync(IQueryable collection, CancellationToken cancellationToken) where T : class 157 | { 158 | await QueryableExtensions.LoadAsync(collection, cancellationToken); 159 | } 160 | 161 | public async Task LongCountAsync(IQueryable collection) where T : class 162 | { 163 | return await QueryableExtensions.LongCountAsync(collection); 164 | } 165 | 166 | public async Task LongCountAsync(IQueryable collection, CancellationToken cancellationToken) where T : class 167 | { 168 | return await QueryableExtensions.LongCountAsync(collection, cancellationToken); 169 | } 170 | 171 | public async Task LongCountAsync(IQueryable collection, Expression> selector) where T : class 172 | { 173 | return await QueryableExtensions.LongCountAsync(collection, selector); 174 | } 175 | 176 | public async Task LongCountAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class 177 | { 178 | return await QueryableExtensions.LongCountAsync(collection, selector, cancellationToken); 179 | } 180 | 181 | public async Task MaxAsync(IQueryable collection) where T : class 182 | { 183 | return await QueryableExtensions.MaxAsync(collection); 184 | } 185 | 186 | public async Task MaxAsync(IQueryable collection, CancellationToken cancellationToken) where T : class 187 | { 188 | return await QueryableExtensions.MaxAsync(collection, cancellationToken); 189 | } 190 | 191 | public async Task MaxAsync(IQueryable collection, Expression> selector) where T : class 192 | { 193 | return await QueryableExtensions.MaxAsync(collection, selector); 194 | } 195 | 196 | public async Task MaxAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class 197 | { 198 | return await QueryableExtensions.MaxAsync(collection, selector, cancellationToken); 199 | } 200 | 201 | public async Task MinAsync(IQueryable collection) where T : class 202 | { 203 | return await QueryableExtensions.MinAsync(collection); 204 | } 205 | 206 | public async Task MinAsync(IQueryable collection, CancellationToken cancellationToken) where T : class 207 | { 208 | return await QueryableExtensions.MinAsync(collection, cancellationToken); 209 | } 210 | 211 | public async Task MinAsync(IQueryable collection, Expression> selector) where T : class 212 | { 213 | return await QueryableExtensions.MinAsync(collection, selector); 214 | } 215 | 216 | public async Task MinAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class 217 | { 218 | return await QueryableExtensions.MinAsync(collection, selector, cancellationToken); 219 | } 220 | 221 | public async Task SingleAsync(IQueryable collection) where T : class 222 | { 223 | return await QueryableExtensions.SingleAsync(collection); 224 | } 225 | 226 | public async Task SingleAsync(IQueryable collection, CancellationToken cancellationToken) where T : class 227 | { 228 | return await QueryableExtensions.SingleAsync(collection, cancellationToken); 229 | } 230 | 231 | public async Task SingleAsync(IQueryable collection, Expression> selector) where T : class 232 | { 233 | return await QueryableExtensions.SingleAsync(collection, selector); 234 | } 235 | 236 | public async Task SingleAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class 237 | { 238 | return await QueryableExtensions.SingleAsync(collection, selector, cancellationToken); 239 | } 240 | 241 | public async Task SingleOrDefaultAsync(IQueryable collection) where T : class 242 | { 243 | return await QueryableExtensions.SingleOrDefaultAsync(collection); 244 | } 245 | 246 | public async Task SingleOrDefaultAsync(IQueryable collection, CancellationToken cancellationToken) where T : class 247 | { 248 | return await QueryableExtensions.SingleOrDefaultAsync(collection, cancellationToken); 249 | } 250 | 251 | public async Task SingleOrDefaultAsync(IQueryable collection, Expression> selector) where T : class 252 | { 253 | return await QueryableExtensions.SingleOrDefaultAsync(collection, selector); 254 | } 255 | 256 | public async Task SingleOrDefaultAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) where T : class 257 | { 258 | return await QueryableExtensions.SingleOrDefaultAsync(collection, selector, cancellationToken); 259 | } 260 | 261 | public IQueryable Skip(IQueryable collection, Expression> countAccessor) where T : class 262 | { 263 | return QueryableExtensions.Skip(collection, countAccessor); 264 | } 265 | 266 | public IQueryable Take(IQueryable collection, Expression> countAccessor) where T : class 267 | { 268 | return QueryableExtensions.Take(collection, countAccessor); 269 | } 270 | 271 | public async Task ToArrayAsync(IQueryable collection) where T : class 272 | { 273 | return await QueryableExtensions.ToArrayAsync(collection); 274 | } 275 | 276 | public async Task ToArrayAsync(IQueryable collection, CancellationToken cancellationToken) where T : class 277 | { 278 | return await QueryableExtensions.ToArrayAsync(collection, cancellationToken); 279 | } 280 | 281 | public async Task> ToDictionaryAsync(IQueryable collection, Func keySelector) where T : class 282 | { 283 | return await QueryableExtensions.ToDictionaryAsync(collection, keySelector); 284 | } 285 | 286 | public async Task> ToDictionaryAsync(IQueryable collection, Func keySelector, CancellationToken cancellationToken) where T : class 287 | { 288 | return await QueryableExtensions.ToDictionaryAsync(collection, keySelector, cancellationToken); 289 | } 290 | 291 | public async Task> ToDictionaryAsync(IQueryable collection, Func keySelector, IEqualityComparer comparer ) where T : class 292 | { 293 | return await QueryableExtensions.ToDictionaryAsync(collection, keySelector, comparer); 294 | } 295 | 296 | public async Task> ToDictionaryAsync(IQueryable collection, Func keySelector, IEqualityComparer comparer , CancellationToken cancellationToken) where T : class 297 | { 298 | return await QueryableExtensions.ToDictionaryAsync(collection, keySelector, comparer, cancellationToken); 299 | } 300 | 301 | public async Task> ToDictionaryAsync(IQueryable collection, Func keySelector, Func elementSelector) where T : class 302 | { 303 | return await QueryableExtensions.ToDictionaryAsync(collection, keySelector, elementSelector); 304 | } 305 | 306 | public async Task> ToDictionaryAsync(IQueryable collection, Func keySelector, Func elementSelector, CancellationToken cancellationToken) where T : class 307 | { 308 | return await QueryableExtensions.ToDictionaryAsync(collection, keySelector, elementSelector, cancellationToken); 309 | } 310 | 311 | public async Task> ToDictionaryAsync(IQueryable collection, Func keySelector, Func elementSelector, IEqualityComparer comparer ) where T : class 312 | { 313 | return await QueryableExtensions.ToDictionaryAsync(collection, keySelector, elementSelector, comparer); 314 | } 315 | 316 | public async Task> ToDictionaryAsync(IQueryable collection, Func keySelector, Func elementSelector, IEqualityComparer comparer , CancellationToken cancellationToken) where T : class 317 | { 318 | return await QueryableExtensions.ToDictionaryAsync(collection, keySelector, elementSelector, comparer, cancellationToken); 319 | } 320 | 321 | public async Task> ToListAsync(IQueryable collection) where T : class 322 | { 323 | return await QueryableExtensions.ToListAsync(collection); 324 | } 325 | 326 | public async Task> ToListAsync(IQueryable collection, CancellationToken cancellationToken) where T : class 327 | { 328 | return await QueryableExtensions.ToListAsync(collection, cancellationToken); 329 | } 330 | } 331 | // ReSharper restore InvokeAsExtensionMethod 332 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/SampleContext.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | using CommandQuerySample.Domain; 3 | 4 | namespace CommandQueryExample.Data 5 | { 6 | public class SampleContext : DbContext 7 | { 8 | public DbSet People { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/SumAsyncExtensionsUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using CommandQueryExample.Common; 8 | using CommandQueryExample.Common.Extensions; 9 | 10 | namespace CommandQueryExample.Data 11 | { 12 | // ReSharper disable InvokeAsExtensionMethod 13 | public partial class SumAsyncExtensionsUtil : ISumAsyncExtensionsUtil 14 | { 15 | public async Task SumAsync(IQueryable collection) 16 | { 17 | return await QueryableExtensions.SumAsync(collection); 18 | } 19 | 20 | public async Task SumAsync(IQueryable collection, CancellationToken cancellationToken) 21 | { 22 | return await QueryableExtensions.SumAsync(collection, cancellationToken); 23 | } 24 | 25 | public async Task SumAsync(IQueryable collection) 26 | { 27 | return await QueryableExtensions.SumAsync(collection); 28 | } 29 | 30 | public async Task SumAsync(IQueryable collection, CancellationToken cancellationToken) 31 | { 32 | return await QueryableExtensions.SumAsync(collection, cancellationToken); 33 | } 34 | 35 | public async Task SumAsync(IQueryable collection) 36 | { 37 | return await QueryableExtensions.SumAsync(collection); 38 | } 39 | 40 | public async Task SumAsync(IQueryable collection, CancellationToken cancellationToken) 41 | { 42 | return await QueryableExtensions.SumAsync(collection, cancellationToken); 43 | } 44 | 45 | public async Task SumAsync(IQueryable collection) 46 | { 47 | return await QueryableExtensions.SumAsync(collection); 48 | } 49 | 50 | public async Task SumAsync(IQueryable collection, CancellationToken cancellationToken) 51 | { 52 | return await QueryableExtensions.SumAsync(collection, cancellationToken); 53 | } 54 | 55 | public async Task SumAsync(IQueryable collection) 56 | { 57 | return await QueryableExtensions.SumAsync(collection); 58 | } 59 | 60 | public async Task SumAsync(IQueryable collection, CancellationToken cancellationToken) 61 | { 62 | return await QueryableExtensions.SumAsync(collection, cancellationToken); 63 | } 64 | 65 | public async Task SumAsync(IQueryable collection) 66 | { 67 | return await QueryableExtensions.SumAsync(collection); 68 | } 69 | 70 | public async Task SumAsync(IQueryable collection, CancellationToken cancellationToken) 71 | { 72 | return await QueryableExtensions.SumAsync(collection, cancellationToken); 73 | } 74 | 75 | public async Task SumAsync(IQueryable collection) 76 | { 77 | return await QueryableExtensions.SumAsync(collection); 78 | } 79 | 80 | public async Task SumAsync(IQueryable collection, CancellationToken cancellationToken) 81 | { 82 | return await QueryableExtensions.SumAsync(collection, cancellationToken); 83 | } 84 | 85 | public async Task SumAsync(IQueryable collection) 86 | { 87 | return await QueryableExtensions.SumAsync(collection); 88 | } 89 | 90 | public async Task SumAsync(IQueryable collection, CancellationToken cancellationToken) 91 | { 92 | return await QueryableExtensions.SumAsync(collection, cancellationToken); 93 | } 94 | 95 | public async Task SumAsync(IQueryable collection) 96 | { 97 | return await QueryableExtensions.SumAsync(collection); 98 | } 99 | 100 | public async Task SumAsync(IQueryable collection, CancellationToken cancellationToken) 101 | { 102 | return await QueryableExtensions.SumAsync(collection, cancellationToken); 103 | } 104 | 105 | public async Task SumAsync(IQueryable collection) 106 | { 107 | return await QueryableExtensions.SumAsync(collection); 108 | } 109 | 110 | public async Task SumAsync(IQueryable collection, CancellationToken cancellationToken) 111 | { 112 | return await QueryableExtensions.SumAsync(collection, cancellationToken); 113 | } 114 | 115 | public async Task SumAsync(IQueryable collection, Expression> selector) 116 | { 117 | return await QueryableExtensions.SumAsync(collection, selector); 118 | } 119 | 120 | public async Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 121 | { 122 | return await QueryableExtensions.SumAsync(collection, selector, cancellationToken); 123 | } 124 | 125 | public async Task SumAsync(IQueryable collection, Expression> selector) 126 | { 127 | return await QueryableExtensions.SumAsync(collection, selector); 128 | } 129 | 130 | public async Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 131 | { 132 | return await QueryableExtensions.SumAsync(collection, selector, cancellationToken); 133 | } 134 | 135 | public async Task SumAsync(IQueryable collection, Expression> selector) 136 | { 137 | return await QueryableExtensions.SumAsync(collection, selector); 138 | } 139 | 140 | public async Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 141 | { 142 | return await QueryableExtensions.SumAsync(collection, selector, cancellationToken); 143 | } 144 | 145 | public async Task SumAsync(IQueryable collection, Expression> selector) 146 | { 147 | return await QueryableExtensions.SumAsync(collection, selector); 148 | } 149 | 150 | public async Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 151 | { 152 | return await QueryableExtensions.SumAsync(collection, selector, cancellationToken); 153 | } 154 | 155 | public async Task SumAsync(IQueryable collection, Expression> selector) 156 | { 157 | return await QueryableExtensions.SumAsync(collection, selector); 158 | } 159 | 160 | public async Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 161 | { 162 | return await QueryableExtensions.SumAsync(collection, selector, cancellationToken); 163 | } 164 | 165 | public async Task SumAsync(IQueryable collection, Expression> selector) 166 | { 167 | return await QueryableExtensions.SumAsync(collection, selector); 168 | } 169 | 170 | public async Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 171 | { 172 | return await QueryableExtensions.SumAsync(collection, selector, cancellationToken); 173 | } 174 | 175 | public async Task SumAsync(IQueryable collection, Expression> selector) 176 | { 177 | return await QueryableExtensions.SumAsync(collection, selector); 178 | } 179 | 180 | public async Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 181 | { 182 | return await QueryableExtensions.SumAsync(collection, selector, cancellationToken); 183 | } 184 | 185 | public async Task SumAsync(IQueryable collection, Expression> selector) 186 | { 187 | return await QueryableExtensions.SumAsync(collection, selector); 188 | } 189 | 190 | public async Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 191 | { 192 | return await QueryableExtensions.SumAsync(collection, selector, cancellationToken); 193 | } 194 | 195 | public async Task SumAsync(IQueryable collection, Expression> selector) 196 | { 197 | return await QueryableExtensions.SumAsync(collection, selector); 198 | } 199 | 200 | public async Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 201 | { 202 | return await QueryableExtensions.SumAsync(collection, selector, cancellationToken); 203 | } 204 | 205 | public async Task SumAsync(IQueryable collection, Expression> selector) 206 | { 207 | return await QueryableExtensions.SumAsync(collection, selector); 208 | } 209 | 210 | public async Task SumAsync(IQueryable collection, Expression> selector, CancellationToken cancellationToken) 211 | { 212 | return await QueryableExtensions.SumAsync(collection, selector, cancellationToken); 213 | } 214 | 215 | public void OnStartup() 216 | { 217 | SumAsyncExtensions.Util = this; 218 | } 219 | } 220 | // ReSharper restore InvokeAsExtensionMethod 221 | } -------------------------------------------------------------------------------- /src/CommandQueryExample.Data/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /src/CommandQueryExample.Tests/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/CommandQueryExample.Tests/CommandQueryExample.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5A1C0F1F-FE2B-424E-9BB3-A6DC994DDE6C} 8 | Library 9 | Properties 10 | CommandQueryExample.Tests 11 | CommandQueryExample.Tests 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\EntityFramework.6.1.2\lib\net45\EntityFramework.dll 35 | 36 | 37 | ..\packages\EntityFramework.6.1.2\lib\net45\EntityFramework.SqlServer.dll 38 | 39 | 40 | ..\packages\FakeItEasy.1.25.2\lib\net40\FakeItEasy.dll 41 | 42 | 43 | ..\packages\Fixie.1.0.0.3\lib\net45\Fixie.dll 44 | 45 | 46 | ..\packages\Should.1.1.20\lib\Should.dll 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 72 | -------------------------------------------------------------------------------- /src/CommandQueryExample.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | 8 | [assembly: AssemblyTitle("CommandQueryExample.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CommandQueryExample.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | 25 | [assembly: Guid("1665e107-c9c5-4541-9a71-6747df1d7a20")] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Build and Revision Numbers 35 | // by using the '*' as shown below: 36 | // [assembly: AssemblyVersion("1.0.*")] 37 | 38 | [assembly: AssemblyVersion("1.0.0.0")] 39 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /src/CommandQueryExample.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 7 | 10 | 13 | 16 | -------------------------------------------------------------------------------- /src/CommandQueryExample.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandQueryExample", "CommandQueryExample\CommandQueryExample.csproj", "{DF3FE8C4-9D9C-4C3F-B0E4-77A0D09889E2}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandQuerySample.Domain", "CommandQuerySample.Domain\CommandQuerySample.Domain.csproj", "{38497722-422D-40CC-B841-279AEF0F7543}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandQueryExample.Data", "CommandQueryExample.Data\CommandQueryExample.Data.csproj", "{E1E7F9EA-040C-405E-8F98-8E40AB6B6857}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandQueryExample.Common", "CommandQueryExample.Common\CommandQueryExample.Common.csproj", "{91D84F63-79B8-4DC5-A822-EEA3E65C26A4}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandQueryExample.Tests", "CommandQueryExample.Tests\CommandQueryExample.Tests.csproj", "{5A1C0F1F-FE2B-424E-9BB3-A6DC994DDE6C}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Any CPU = Debug|Any CPU 19 | Release|Any CPU = Release|Any CPU 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {DF3FE8C4-9D9C-4C3F-B0E4-77A0D09889E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {DF3FE8C4-9D9C-4C3F-B0E4-77A0D09889E2}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {DF3FE8C4-9D9C-4C3F-B0E4-77A0D09889E2}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {DF3FE8C4-9D9C-4C3F-B0E4-77A0D09889E2}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {38497722-422D-40CC-B841-279AEF0F7543}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {38497722-422D-40CC-B841-279AEF0F7543}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {38497722-422D-40CC-B841-279AEF0F7543}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {38497722-422D-40CC-B841-279AEF0F7543}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {E1E7F9EA-040C-405E-8F98-8E40AB6B6857}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {E1E7F9EA-040C-405E-8F98-8E40AB6B6857}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {E1E7F9EA-040C-405E-8F98-8E40AB6B6857}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {E1E7F9EA-040C-405E-8F98-8E40AB6B6857}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {91D84F63-79B8-4DC5-A822-EEA3E65C26A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {91D84F63-79B8-4DC5-A822-EEA3E65C26A4}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {91D84F63-79B8-4DC5-A822-EEA3E65C26A4}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {91D84F63-79B8-4DC5-A822-EEA3E65C26A4}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {5A1C0F1F-FE2B-424E-9BB3-A6DC994DDE6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {5A1C0F1F-FE2B-424E-9BB3-A6DC994DDE6C}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {5A1C0F1F-FE2B-424E-9BB3-A6DC994DDE6C}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {5A1C0F1F-FE2B-424E-9BB3-A6DC994DDE6C}.Release|Any CPU.Build.0 = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | EndGlobal 47 | -------------------------------------------------------------------------------- /src/CommandQueryExample/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/CommandQueryExample/CommandQueryExample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DF3FE8C4-9D9C-4C3F-B0E4-77A0D09889E2} 8 | Exe 9 | Properties 10 | CommandQueryExample 11 | CommandQueryExample 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | False 37 | ..\packages\EntityFramework.6.1.2\lib\net45\EntityFramework.dll 38 | 39 | 40 | ..\packages\EntityFramework.6.1.2\lib\net45\EntityFramework.SqlServer.dll 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | {91D84F63-79B8-4DC5-A822-EEA3E65C26A4} 65 | CommandQueryExample.Common 66 | 67 | 68 | {E1E7F9EA-040C-405E-8F98-8E40AB6B6857} 69 | CommandQueryExample.Data 70 | 71 | 72 | {38497722-422D-40CC-B841-279AEF0F7543} 73 | CommandQuerySample.Domain 74 | 75 | 76 | 77 | 84 | -------------------------------------------------------------------------------- /src/CommandQueryExample/CreatePersonCommand.cs: -------------------------------------------------------------------------------- 1 | using CommandQueryExample.Common; 2 | using CommandQueryExample.Common.Extensions; 3 | using CommandQuerySample.Domain; 4 | 5 | namespace CommandQueryExample 6 | { 7 | public class CreatePersonCommand : BaseCommand 8 | { 9 | public CreatePersonCommand(string firstName, string lastName) 10 | { 11 | Action = s => s.Add(new Person {FirstName = firstName, LastName = lastName}); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/CommandQueryExample/GetPeopleByFirstNameQuery.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using CommandQueryExample.Common; 3 | using CommandQuerySample.Domain; 4 | 5 | namespace CommandQueryExample 6 | { 7 | public class GetPeopleByFirstNameQuery : BaseQuery 8 | { 9 | public GetPeopleByFirstNameQuery(string firstName) 10 | { 11 | Query = s => s.Where(x => x.FirstName == firstName).ToList(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/CommandQueryExample/Log4Net.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/CommandQueryExample/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CommandQueryExample.Common; 4 | using CommandQueryExample.Common.Extensions; 5 | using CommandQueryExample.Common.StandardCommands; 6 | using CommandQueryExample.Data; 7 | using CommandQuerySample.Domain; 8 | 9 | namespace CommandQueryExample 10 | { 11 | internal class Program 12 | { 13 | static void Main(string[] args) 14 | { 15 | // These tasks are usually handled by my IoC bootstrapper 16 | new QueryExtensionsUtil().OnStartup(); 17 | new SumAsyncExtensionsUtil().OnStartup(); 18 | new AverageAsyncExtensionsUtil().OnStartup(); 19 | new DbSetExtensionsUtil().OnStartup(); 20 | new DataContextFactoryStartupTask().OnStartup(); 21 | 22 | // this would normally be injected on the constructor 23 | IDispatcher dispatcher = new Dispatcher(); 24 | 25 | using (var context = DataContextFactory.CreateDataContext()) 26 | { 27 | var query = new GetPeopleByFirstNameQuery("Alan"); 28 | PrintPeople(dispatcher.Get(query)); 29 | 30 | var command = new AddCommand(new Person {FirstName = "Alan", LastName = "Turing"}); 31 | dispatcher.QueueCommand(command); 32 | 33 | var mutableAlan = new Person {FirstName = "Alan", LastName = "Shepard"}; 34 | 35 | dispatcher.Add(mutableAlan); // Using an IDispatcher extension method 36 | 37 | context.SaveChanges(); 38 | 39 | PrintPeople(dispatcher.Get(query)); 40 | 41 | mutableAlan.LastName = "Alda"; 42 | dispatcher.QueueCommand(new UpdateCommand(mutableAlan)); // Not strictly needed 43 | 44 | PrintPeople(dispatcher.Get(query)); 45 | 46 | dispatcher.QueueCommand(new RemoveCommand(mutableAlan)); 47 | 48 | context.SaveChanges(); 49 | 50 | PrintPeople(dispatcher.Get(query)); 51 | } 52 | Console.Read(); 53 | } 54 | 55 | static void PrintPeople(IEnumerable people) 56 | { 57 | foreach (var person in people) 58 | Console.WriteLine(person.FullName); 59 | 60 | Console.WriteLine(); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /src/CommandQueryExample/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | 8 | [assembly: AssemblyTitle("CommandQueryExample")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CommandQueryExample")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | 25 | [assembly: Guid("40f21e4c-efcf-49c5-b750-89e60a8d4867")] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Build and Revision Numbers 35 | // by using the '*' as shown below: 36 | // [assembly: AssemblyVersion("1.0.*")] 37 | 38 | [assembly: AssemblyVersion("1.0.0.0")] 39 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /src/CommandQueryExample/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /src/CommandQuerySample.Domain/CommandQuerySample.Domain.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {38497722-422D-40CC-B841-279AEF0F7543} 8 | Library 9 | Properties 10 | CommandQuerySample.Domain 11 | CommandQuerySample.Domain 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 54 | -------------------------------------------------------------------------------- /src/CommandQuerySample.Domain/Person.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations.Schema; 2 | 3 | namespace CommandQuerySample.Domain 4 | { 5 | public class Person 6 | { 7 | public int Id { get; set; } 8 | 9 | public string FirstName { get; set; } 10 | 11 | public string LastName { get; set; } 12 | 13 | [NotMapped] 14 | public string FullName { get { return FirstName + " " + LastName; } } 15 | } 16 | } -------------------------------------------------------------------------------- /src/CommandQuerySample.Domain/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | 8 | [assembly: AssemblyTitle("CommandQuerySample.Domain")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CommandQuerySample.Domain")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | 25 | [assembly: Guid("f8e190f3-fd0f-497b-802e-7040c408b6ef")] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Build and Revision Numbers 35 | // by using the '*' as shown below: 36 | // [assembly: AssemblyVersion("1.0.*")] 37 | 38 | [assembly: AssemblyVersion("1.0.0.0")] 39 | [assembly: AssemblyFileVersion("1.0.0.0")] --------------------------------------------------------------------------------