Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
rasmus committed Oct 25, 2017
2 parents 5655d79 + 9e082a7 commit d518e36
Show file tree
Hide file tree
Showing 44 changed files with 222 additions and 100 deletions.
12 changes: 11 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
### New in 0.50 (not released yet)
### New in 0.51 (not released yet)

* New: Removed the `new()` requirement for read models
* New: If `ISagaLocator.LocateSagaAsync` cannot identify the saga for a given
event, it may now return `Task.FromResult(null)` in order to short-circuit
the dispatching process. This might be useful in cases where some instances
of an event belong to a saga process while others don't
* Fixed: `StringExtensions.ToSha256()` can now be safely used from
concurrent threads.

### New in 0.50.3124 (released 2017-10-21)

* New: While EventFlow tries to limit the about of painful API changes, the
introduction of execution/command results are considered a necessary step
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static IEventFlowOptions ConfigureElasticsearch(

public static IEventFlowOptions UseElasticsearchReadModel<TReadModel>(
this IEventFlowOptions eventFlowOptions)
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
{
return eventFlowOptions
.RegisterServices(f =>
Expand All @@ -89,7 +89,7 @@ public static IEventFlowOptions UseElasticsearchReadModel<TReadModel>(

public static IEventFlowOptions UseElasticsearchReadModel<TReadModel, TReadModelLocator>(
this IEventFlowOptions eventFlowOptions)
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
where TReadModelLocator : IReadModelLocator
{
return eventFlowOptions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace EventFlow.Elasticsearch.ReadStores
{
public class ElasticsearchReadModelStore<TReadModel> :
IElasticsearchReadModelStore<TReadModel>
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
{
private readonly ILog _log;
private readonly IElasticClient _elasticClient;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
namespace EventFlow.Elasticsearch.ReadStores
{
public interface IElasticsearchReadModelStore<TReadModel> : IReadModelStore<TReadModel>
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static class EventFlowOptionsMsSqlReadStoreExtensions
{
public static IEventFlowOptions UseMssqlReadModel<TReadModel, TReadModelLocator>(
this IEventFlowOptions eventFlowOptions)
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
where TReadModelLocator : IReadModelLocator
{
return eventFlowOptions
Expand All @@ -48,7 +48,7 @@ public static IEventFlowOptions UseMssqlReadModel<TReadModel, TReadModelLocator>

public static IEventFlowOptions UseMssqlReadModel<TReadModel>(
this IEventFlowOptions eventFlowOptions)
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
{
return eventFlowOptions
.RegisterServices(f =>
Expand Down
2 changes: 1 addition & 1 deletion Source/EventFlow.MsSql/Integrations/TableParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
namespace EventFlow.MsSql.Integrations
{
internal class TableParameter<TRow> : SqlMapper.IDynamicParameters
where TRow : class, new()
where TRow : class
{
private readonly string _name;
private readonly IEnumerable<TRow> _rows;
Expand Down
2 changes: 1 addition & 1 deletion Source/EventFlow.MsSql/ReadStores/IMssqlReadModelStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
namespace EventFlow.MsSql.ReadStores
{
public interface IMssqlReadModelStore<TReadModel> : IReadModelStore<TReadModel>
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
{
}
}
2 changes: 1 addition & 1 deletion Source/EventFlow.MsSql/ReadStores/MssqlReadModelStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace EventFlow.MsSql.ReadStores
public class MssqlReadModelStore<TReadModel> :
ReadModelStore<TReadModel>,
IMssqlReadModelStore<TReadModel>
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
{
private readonly IMsSqlConnection _connection;
private readonly IReadModelSqlGenerator _readModelSqlGenerator;
Expand Down
1 change: 1 addition & 0 deletions Source/EventFlow.Owin.Tests/EventFlow.Owin.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.WebApi2" Version="4.0.0" />
<PackageReference Include="Autofac.WebApi2.Owin" Version="4.0.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.2.3" />
<PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="3.1.0" />
Expand Down
4 changes: 4 additions & 0 deletions Source/EventFlow.Owin.Tests/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="4.5.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac.Integration.WebApi" publicKeyToken="17863af14b0044da" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="4.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="3.1.0.0"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public static IEventFlowOptions UseSQLiteEventStore(

public static IEventFlowOptions UseSQLiteReadModel<TReadModel, TReadModelLocator>(
this IEventFlowOptions eventFlowOptions)
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
where TReadModelLocator : IReadModelLocator
{
return eventFlowOptions
Expand All @@ -72,7 +72,7 @@ public static IEventFlowOptions UseSQLiteReadModel<TReadModel, TReadModelLocator

public static IEventFlowOptions UseSQLiteReadModel<TReadModel>(
this IEventFlowOptions eventFlowOptions)
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
{
return eventFlowOptions
.RegisterServices(f =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
namespace EventFlow.SQLite.ReadStores
{
public interface ISQLiteReadModelStore<TReadModel> : ISqlReadModelStore<TReadModel>
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
{
}
}
2 changes: 1 addition & 1 deletion Source/EventFlow.SQLite/ReadStores/SQLiteReadModelStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
namespace EventFlow.SQLite.ReadStores
{
public class SQLiteReadModelStore<TReadModel> : SqlReadModelStore<ISQLiteConnection, TReadModel>, ISQLiteReadModelStore<TReadModel>
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
{
public SQLiteReadModelStore(
ILog log,
Expand Down
2 changes: 1 addition & 1 deletion Source/EventFlow.Sql/Connections/ISqlConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Task<IReadOnlyCollection<TResult>> InsertMultipleAsync<TResult, TRow>(
CancellationToken cancellationToken,
string sql,
IEnumerable<TRow> rows)
where TRow : class, new();
where TRow : class;

Task<TResult> WithConnectionAsync<TResult>(
Label label,
Expand Down
2 changes: 1 addition & 1 deletion Source/EventFlow.Sql/Connections/SqlConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public virtual Task<IReadOnlyCollection<TResult>> InsertMultipleAsync<TResult, T
CancellationToken cancellationToken,
string sql,
IEnumerable<TRow> rows)
where TRow : class, new()
where TRow : class
{
Log.Debug(
"Insert multiple not optimised, inserting one row at a time using SQL '{0}'",
Expand Down
2 changes: 1 addition & 1 deletion Source/EventFlow.Sql/ReadModels/ISqlReadModelStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
namespace EventFlow.Sql.ReadModels
{
public interface ISqlReadModelStore<TReadModel> : IReadModelStore<TReadModel>
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
{
}
}
2 changes: 1 addition & 1 deletion Source/EventFlow.Sql/ReadModels/SqlReadModelStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace EventFlow.Sql.ReadModels
public abstract class SqlReadModelStore<TSqlConnection, TReadModel> :
ReadModelStore<TReadModel>,
ISqlReadModelStore<TReadModel>
where TReadModel : class, IReadModel, new()
where TReadModel : class, IReadModel
where TSqlConnection : ISqlConnection
{
private readonly TSqlConnection _connection;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
using EventFlow.Core;
using EventFlow.Sagas;
using EventFlow.ValueObjects;
using FluentAssertions;

namespace EventFlow.Tests.IntegrationTests.Sagas
{
Expand All @@ -48,6 +49,12 @@ public class InMemorySagaStore : ISagaStore
{
private readonly Dictionary<ISagaId, object> _sagas = new Dictionary<ISagaId, object>();
private readonly AsyncLock _asyncLock = new AsyncLock();
private bool _hasUpdateBeenCalled;

public void UpdateShouldNotHaveBeenCalled()
{
this._hasUpdateBeenCalled.Should().BeFalse();
}

public async Task<TSaga> UpdateAsync<TSaga>(
ISagaId sagaId,
Expand All @@ -59,10 +66,11 @@ public async Task<TSaga> UpdateAsync<TSaga>(
{
using (await _asyncLock.WaitAsync(cancellationToken).ConfigureAwait(false))
{
object obj;
if (!_sagas.TryGetValue(sagaId, out obj))
_hasUpdateBeenCalled = true;

if (!_sagas.TryGetValue(sagaId, out var obj))
{
obj = Activator.CreateInstance(sagaDetails.SagaType, new object[] {sagaId});
obj = Activator.CreateInstance(sagaDetails.SagaType, sagaId);
_sagas[sagaId] = obj;
}

Expand Down Expand Up @@ -141,7 +149,13 @@ public class TestSagaLocator : ISagaLocator
{
public Task<ISagaId> LocateSagaAsync(IDomainEvent domainEvent, CancellationToken cancellationToken)
{
return Task.FromResult<ISagaId>(new TestSagaId($"saga-for-{domainEvent.GetIdentity().Value}"));
var identity = domainEvent.GetIdentity().Value;
if (identity.EndsWith(Guid.Empty.ToString()))
{
return Task.FromResult<ISagaId>(null);
}

return Task.FromResult<ISagaId>(new TestSagaId($"saga-for-{identity}"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.Threading;
using System.Threading.Tasks;
using EventFlow.Aggregates;
Expand All @@ -39,6 +40,7 @@ public class AlternativeSagaStoreTests
private IRootResolver _resolver;
private ICommandBus _commandBus;
private IAggregateStore _aggregateStore;
private AlternativeSagaStoreTestClasses.InMemorySagaStore _sagaStore;

[SetUp]
public void SetUp()
Expand All @@ -54,14 +56,15 @@ public void SetUp()
typeof(AlternativeSagaStoreTestClasses.SagaTestEventB),
typeof(AlternativeSagaStoreTestClasses.SagaTestEventC))
.RegisterServices(sr =>
{
sr.RegisterType(typeof(AlternativeSagaStoreTestClasses.TestSagaLocator));
sr.Register<ISagaStore, AlternativeSagaStoreTestClasses.InMemorySagaStore>(Lifetime.Singleton);
})
{
sr.RegisterType(typeof(AlternativeSagaStoreTestClasses.TestSagaLocator));
sr.Register<ISagaStore, AlternativeSagaStoreTestClasses.InMemorySagaStore>(Lifetime.Singleton);
})
.CreateResolver(false);

_commandBus = _resolver.Resolve<ICommandBus>();
_aggregateStore = _resolver.Resolve<IAggregateStore>();
_sagaStore = (AlternativeSagaStoreTestClasses.InMemorySagaStore) _resolver.Resolve<ISagaStore>();
}

[TearDown]
Expand Down Expand Up @@ -101,5 +104,31 @@ public async Task NotStarted()
testAggregate.Bs.Should().Be(1);
testAggregate.Cs.Should().Be(0);
}

[Test]
public void SagaLocatorReturningNullDoesntThrow()
{
// Arrange
var aggregateId = AlternativeSagaStoreTestClasses.SagaTestAggregateId.With(Guid.Empty);

// Act
Action action = () => _commandBus.Publish(new AlternativeSagaStoreTestClasses.SagaTestBCommand(aggregateId), CancellationToken.None);

// Assert
action.ShouldNotThrow();
}

[Test]
public void SagaLocatorReturningNullDoesntCallSagaStore()
{
// Arrange
var aggregateId = AlternativeSagaStoreTestClasses.SagaTestAggregateId.With(Guid.Empty);

// Act
_commandBus.Publish(new AlternativeSagaStoreTestClasses.SagaTestBCommand(aggregateId), CancellationToken.None);

// Assert
_sagaStore.UpdateShouldNotHaveBeenCalled();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,19 @@
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.Threading;
using System.Threading.Tasks;
using EventFlow.Logs;
using EventFlow.ReadStores;
using EventFlow.TestHelpers;
using FluentAssertions;
using NUnit.Framework;

// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable UnusedMember.Global

namespace EventFlow.Tests.UnitTests.ReadStores
{
[Category(Categories.Unit)]
Expand Down Expand Up @@ -61,6 +67,23 @@ public async Task ReadModelFactoryCanBeConfigured()
}
}

[Test]
public void ThrowsExceptionForNoEmptyConstruuctors()
{
// Act + Assert
var exception = Assert.Throws<TypeInitializationException>(() => new ReadModelFactory<ReadModelWithConstructorArguments>(Mock<ILog>()));

// Assert
// ReSharper disable once PossibleNullReferenceException
exception.InnerException.Message.Should().Contain("doesn't have an empty constructor");
}

public class ReadModelWithConstructorArguments : IReadModel
{
// ReSharper disable once UnusedParameter.Local
public ReadModelWithConstructorArguments(int magicNumber){ }
}

public interface IFancyReadModel : IReadModel
{
int MagicNumber { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ public void SetUp()
.Returns(_sagaUpdaterMock.Object);
_sagaDefinitionServiceMock
.Setup(d => d.GetSagaDetails(It.IsAny<Type>()))
.Returns(new[] {SagaDetails.From(sagaType),});
.Returns(new[] {SagaDetails.From(sagaType)});
_sagaLocatorMock
.Setup(s => s.LocateSagaAsync(It.IsAny<IDomainEvent>(), CancellationToken.None))
.Returns(() => Task.FromResult<ISagaId>(new ThingySagaId(string.Empty)));
}

[Test]
Expand Down
Loading

0 comments on commit d518e36

Please sign in to comment.