Permalink
Browse files

Created a CouchDocumentConvention class to encapsulate the default co…

…nventions. We also allow the user to override these conventions. We also did some refactoring and created a GuidIdentityGenerator.
  • Loading branch information...
1 parent 578535b commit 13d8305ab92500cfb55da2338eed8cac718f6d14 @dragan dragan committed Aug 28, 2010
@@ -0,0 +1,78 @@
+using System;
+using System.Reflection;
+
+using NSubstitute;
+using NUnit.Framework;
+using NUnit.Framework.SyntaxHelpers;
+using SineSignal.Ottoman.Specs.Framework;
+
+using SineSignal.Ottoman;
+using SineSignal.Ottoman.Generators;
+
+namespace SineSignal.Ottoman.Specs
+{
+ public class CouchDocumentConventionSpecs
+ {
+ public class When_retrieving_the_identity_property_info_for_a_given_type : ConcernFor<CouchDocumentConvention>
+ {
+ private string defaultIdentityName;
+ private Employee entity;
+ private PropertyInfo identityProperty;
+
+ protected override void Given()
+ {
+ defaultIdentityName = "Id";
+ entity = new Employee { Id = Guid.NewGuid(), Name = "Bob", Login = "boblogin" };
+ }
+
+ public override CouchDocumentConvention CreateSystemUnderTest ()
+ {
+ return new CouchDocumentConvention();
+ }
+
+ protected override void When()
+ {
+ identityProperty = Sut.GetIdentityPropertyFor(entity.GetType());
+ }
+
+ [Test]
+ public void Should_be_able_to_get_identity_property_info_given_the_name_of_the_property()
+ {
+ Assert.That(identityProperty.Name, Is.EqualTo(defaultIdentityName));
+ }
+ }
+
+ public class When_generating_an_identity_value_for_a_given_identity_type : ConcernFor<CouchDocumentConvention>
+ {
+ private Employee entity;
+ private object generatedValue;
+
+ protected override void Given()
+ {
+ entity = new Employee { Name = "Bob", Login = "boblogin" };
+ }
+
+ public override CouchDocumentConvention CreateSystemUnderTest ()
+ {
+ return new CouchDocumentConvention();
+ }
+
+ protected override void When()
+ {
+ generatedValue = Sut.GenerateIdentityFor(entity.Id.GetType());
+ }
+
+ [Test]
+ public void Should_return_a_Guid_type()
+ {
+ Assert.That(generatedValue, Is.TypeOf(typeof(Guid)));
+ }
+
+ [Test]
+ public void Should_not_return_an_empty_Guid()
+ {
+ Assert.That((Guid)generatedValue, Is.Not.EqualTo(Guid.Empty));
+ }
+ }
+ }
+}
@@ -22,7 +22,7 @@ public class When_storing_a_new_entity_into_the_session : ConcernFor<CouchDocume
private PropertyInfo identityProperty;
private Type identityType;
private Guid id;
- private IDocumentConvention documentConvention;
+ private ICouchDocumentConvention documentConvention;
private ICouchDatabase couchDatabase;
protected override void Given()
@@ -33,12 +33,12 @@ protected override void Given()
identityType = identityProperty.PropertyType;
id = Guid.NewGuid();
- documentConvention = Fake<IDocumentConvention>();
+ documentConvention = Fake<ICouchDocumentConvention>();
documentConvention.GetIdentityPropertyFor(entity1Type).Returns(identityProperty);
documentConvention.GenerateIdentityFor(identityType).Returns(id);
couchDatabase = Fake<ICouchDatabase>();
- couchDatabase.DocumentConvention.Returns(documentConvention);
+ couchDatabase.CouchDocumentConvention.Returns(documentConvention);
}
public override CouchDocumentSession CreateSystemUnderTest()
@@ -83,7 +83,7 @@ public class When_storing_an_entity_with_an_id_already_assigned : ConcernFor<Cou
private Employee entity1;
private Type entity1Type;
private PropertyInfo identityProperty;
- private IDocumentConvention documentConvention;
+ private ICouchDocumentConvention documentConvention;
private ICouchDatabase couchDatabase;
protected override void Given()
@@ -93,11 +93,11 @@ protected override void Given()
entity1Type = entity1.GetType();
identityProperty = entity1Type.GetProperty("Id");
- documentConvention = Fake<IDocumentConvention>();
+ documentConvention = Fake<ICouchDocumentConvention>();
documentConvention.GetIdentityPropertyFor(entity1Type).Returns(identityProperty);
couchDatabase = Fake<ICouchDatabase>();
- couchDatabase.DocumentConvention.Returns(documentConvention);
+ couchDatabase.CouchDocumentConvention.Returns(documentConvention);
}
public override CouchDocumentSession CreateSystemUnderTest()
@@ -144,7 +144,7 @@ public class When_attempting_to_store_a_different_entity_with_the_same_id_as_ano
private Type entity2Type;
private PropertyInfo identityProperty;
private NonUniqueEntityException thrownException;
- private IDocumentConvention documentConvention;
+ private ICouchDocumentConvention documentConvention;
private ICouchDatabase couchDatabase;
protected override void Given()
@@ -155,11 +155,11 @@ protected override void Given()
entity2Type = entity2.GetType();
identityProperty = entity2Type.GetProperty("Id");
- documentConvention = Fake<IDocumentConvention>();
+ documentConvention = Fake<ICouchDocumentConvention>();
documentConvention.GetIdentityPropertyFor(entity2Type).Returns(identityProperty);
couchDatabase = Fake<ICouchDatabase>();
- couchDatabase.DocumentConvention.Returns(documentConvention);
+ couchDatabase.CouchDocumentConvention.Returns(documentConvention);
}
public override CouchDocumentSession CreateSystemUnderTest()
@@ -196,7 +196,7 @@ public class When_saving_changes_after_storing_a_new_entity : ConcernFor<CouchDo
private PropertyInfo identityProperty;
private Type identityType;
private Guid id;
- private IDocumentConvention documentConvention;
+ private ICouchDocumentConvention documentConvention;
private BulkDocsResult[] bulkDocsResults;
private ICouchProxy couchProxy;
private ICouchDatabase couchDatabase;
@@ -209,7 +209,7 @@ protected override void Given()
identityType = identityProperty.PropertyType;
id = Guid.NewGuid();
- documentConvention = Fake<IDocumentConvention>();
+ documentConvention = Fake<ICouchDocumentConvention>();
documentConvention.GetIdentityPropertyFor(entity1Type).Returns(identityProperty);
documentConvention.GenerateIdentityFor(identityType).Returns(id);
@@ -219,7 +219,7 @@ protected override void Given()
couchProxy.Execute<BulkDocsResult[]>(Arg.Any<BulkDocsCommand>()).Returns(bulkDocsResults);
couchDatabase = Fake<ICouchDatabase>();
- couchDatabase.DocumentConvention.Returns(documentConvention);
+ couchDatabase.CouchDocumentConvention.Returns(documentConvention);
couchDatabase.Name.Returns("ottoman-test-database");
couchDatabase.CouchProxy.Returns(couchProxy);
}
@@ -43,6 +43,7 @@
<Compile Include="Serialization\JsonReaderSpecs\ReadingObjectsSpecs.cs" />
<Compile Include="Serialization\JsonReaderSpecs\ReadingArraySpecs.cs" />
<Compile Include="Serialization\JsonSerializerSpecs.cs" />
+ <Compile Include="CouchDocumentConventionSpecs.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SineSignal.Ottoman\SineSignal.Ottoman.csproj">
@@ -11,17 +11,24 @@ public ICouchProxy CouchProxy
get { return CouchClient.CouchProxy; }
}
- public IDocumentConvention DocumentConvention
- {
- get { throw new NotImplementedException(); }
- }
+ public ICouchDocumentConvention CouchDocumentConvention { get; private set; }
public string Name { get; private set; }
- public CouchDatabase(CouchClient couchClient, string name)
+ public CouchDatabase(CouchClient couchClient, string name) : this(couchClient, name, new CouchDocumentConvention())
+ {
+ }
+
+ public CouchDatabase(CouchClient couchClient, string name, ICouchDocumentConvention couchDocumentConvention)
{
CouchClient = couchClient;
Name = name;
+ CouchDocumentConvention = couchDocumentConvention;
+ }
+
+ public ICouchDocumentSession OpenDocumentSession()
+ {
+ return new CouchDocumentSession(this);
}
}
}
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+using SineSignal.Ottoman.Generators;
+
+namespace SineSignal.Ottoman
+{
+ public class CouchDocumentConvention : ICouchDocumentConvention
+ {
+ private static IDictionary<Type, object> identityGenerators = InitializeIdentityGenerators();
+
+ public virtual PropertyInfo GetIdentityPropertyFor(Type entityType)
+ {
+ return entityType.GetProperty("Id");
+ }
+
+ public object GenerateIdentityFor(Type identityType)
+ {
+ object generatedValue = null;
+
+ if (identityType == typeof(Guid))
+ {
+ generatedValue = GetIdentityGeneratorFor<Guid>(identityType).Generate();
+ }
+
+ return generatedValue;
+ }
+
+ private static IDictionary<Type, object> InitializeIdentityGenerators()
+ {
+ IDictionary<Type, object> identityGenerators = new Dictionary<Type, object>();
+
+ identityGenerators.Add(typeof(Guid), new GuidIdentityGenerator());
+
+ return identityGenerators;
+ }
+
+ private static IIdentityGenerator<T> GetIdentityGeneratorFor<T>(Type type)
+ {
+ object generator;
+
+ if (identityGenerators.TryGetValue(type, out generator))
+ {
+ return generator as IIdentityGenerator<T>;
+ }
+
+ return null;
+ }
+ }
+}
@@ -25,7 +25,7 @@ public CouchDocumentSession(ICouchDatabase couchDatabase)
public void Store(object entity)
{
Type entityType = entity.GetType();
- PropertyInfo identityProperty = CouchDatabase.DocumentConvention.GetIdentityPropertyFor(entityType);
+ PropertyInfo identityProperty = CouchDatabase.CouchDocumentConvention.GetIdentityPropertyFor(entityType);
object id = null;
if (identityProperty != null)
@@ -34,7 +34,7 @@ public void Store(object entity)
if (id == null)
{
- id = CouchDatabase.DocumentConvention.GenerateIdentityFor(identityProperty.PropertyType);
+ id = CouchDatabase.CouchDocumentConvention.GenerateIdentityFor(identityProperty.PropertyType);
identityProperty.SetValue(entity, id, null);
}
}
@@ -69,7 +69,7 @@ public void SaveChanges()
var docs = new List<CouchDocument>();
foreach (object entity in IdentityMap.Values)
{
- PropertyInfo identityProperty = CouchDatabase.DocumentConvention.GetIdentityPropertyFor(entity.GetType());
+ PropertyInfo identityProperty = CouchDatabase.CouchDocumentConvention.GetIdentityPropertyFor(entity.GetType());
var couchDocument = new CouchDocument(entity, identityProperty);
docs.Add(couchDocument);
}
@@ -90,10 +90,9 @@ private static object GetIdentityValueFor(object entity, PropertyInfo identityPr
object id = identityProperty.GetValue(entity, null);
Type propertyType = identityProperty.PropertyType;
- if (propertyType == typeof(Guid))
+ if (propertyType == typeof(Guid) && (Guid)id == Guid.Empty)
{
- if ((Guid)id == Guid.Empty)
- id = null;
+ id = null;
}
return id;
@@ -0,0 +1,12 @@
+using System;
+
+namespace SineSignal.Ottoman.Generators
+{
+ public class GuidIdentityGenerator : IIdentityGenerator<Guid>
+ {
+ public Guid Generate()
+ {
+ return Guid.NewGuid();
+ }
+ }
+}
@@ -0,0 +1,9 @@
+using System;
+
+namespace SineSignal.Ottoman.Generators
+{
+ public interface IIdentityGenerator<T>
+ {
+ T Generate();
+ }
+}
@@ -3,7 +3,8 @@ namespace SineSignal.Ottoman
public interface ICouchDatabase
{
ICouchProxy CouchProxy { get; }
- IDocumentConvention DocumentConvention { get; }
+ ICouchDocumentConvention CouchDocumentConvention { get; }
string Name { get; }
+ ICouchDocumentSession OpenDocumentSession();
}
}
@@ -3,7 +3,7 @@
namespace SineSignal.Ottoman
{
- public interface IDocumentConvention
+ public interface ICouchDocumentConvention
{
PropertyInfo GetIdentityPropertyFor(Type entityType);
object GenerateIdentityFor(Type identityType);
@@ -32,7 +32,6 @@
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="CouchDocumentSession.cs" />
- <Compile Include="IDocumentConvention.cs" />
<Compile Include="Exceptions\NonUniqueEntityException.cs" />
<Compile Include="Http\HttpClient.cs" />
<Compile Include="Http\HttpRequest.cs" />
@@ -70,6 +69,10 @@
<Compile Include="Exceptions\CannotGetDatabaseException.cs" />
<Compile Include="Exceptions\CouchException.cs" />
<Compile Include="Exceptions\UnexpectedHttpResponseException.cs" />
+ <Compile Include="ICouchDocumentConvention.cs" />
+ <Compile Include="Generators\IIdentityGenerator.cs" />
+ <Compile Include="Generators\GuidIdentityGenerator.cs" />
+ <Compile Include="CouchDocumentConvention.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
@@ -81,5 +84,6 @@
<Folder Include="Http\" />
<Folder Include="Commands\" />
<Folder Include="Serialization\" />
+ <Folder Include="Generators\" />
</ItemGroup>
</Project>

0 comments on commit 13d8305

Please sign in to comment.