Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Refactored CreateDocument so that Generics work and now a DefaultObje…

…ctSerializer exists on the CouchDatabase. (Which can be overridden if desired).
  • Loading branch information...
commit 2d58b6abb44fe5d7afca7d2527a6cd402d643eb5 1 parent 767ab9a
@soitgoes authored
View
26 LoveSeat.IntegrationTest/CouchClientTest.cs
@@ -1,8 +1,13 @@
using System;
+using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
+using LoveSeat.Interfaces;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Serialization;
using NUnit.Framework;
using LoveSeat;
@@ -167,6 +172,20 @@ public void Should_Persist_Property()
var doc = db.GetDocument<Company>("1234");
Assert.AreEqual(company.Name, doc.Name);
}
+ [Test]
+ public void JsonConvert_Should_Serialize_Properly()
+ {
+ var company = new Company();
+ company.Name = "Whiteboard-it";
+ var settings = new JsonSerializerSettings();
+ var converters = new List<JsonConverter> { new IsoDateTimeConverter() };
+ settings.Converters = converters;
+ settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
+ settings.NullValueHandling = NullValueHandling.Ignore;
+ var result = JsonConvert.SerializeObject(company, Formatting.Indented, settings);
+ Console.Write(result);
+ Assert.IsTrue(result.Contains("Whiteboard-it"));
+ }
[Test]
public void Should_Get_304_If_ETag_Matches()
{
@@ -186,8 +205,11 @@ public void Should_Get_Id_From_Existing_Document()
Assert.AreEqual(id, doc.Id);
}
}
- public class Company :Document
- {
+ public class Company : IBaseObject
+ {
public string Name { get; set; }
+ public string Id { get; set; }
+ public string Rev { get; set; }
+ public string Type { get { return "company"; } }
}
}
View
4 LoveSeat.IntegrationTest/LoveSeat.IntegrationTest.csproj
@@ -60,6 +60,10 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\LoveSeat.Interfaces\LoveSeat.Interfaces.csproj">
+ <Project>{18833FC5-9145-451D-82D4-41A1886B0BE7}</Project>
+ <Name>LoveSeat.Interfaces</Name>
+ </ProjectReference>
<ProjectReference Include="..\LoveSeat\LoveSeat.csproj">
<Project>{AF987164-0100-4A90-A767-D473F882EA8B}</Project>
<Name>LoveSeat</Name>
View
2  LoveSeat.Interfaces/IAuditableRecord.cs
@@ -1,5 +1,5 @@
using System;
-using LoveSeat.Repository;
+using LoveSeat.Interfaces;
namespace Accounting.Domain
{
View
7 LoveSeat.Interfaces/IBaseObject.cs
@@ -1,10 +1,13 @@
using System;
+using Newtonsoft.Json;
-namespace LoveSeat.Repository
+namespace LoveSeat.Interfaces
{
public interface IBaseObject
{
- Guid Id { get; set; }
+ [JsonProperty("_id")]
+ string Id { get; set; }
+ [JsonProperty("_rev")]
string Rev { get; set; }
string Type { get; }
}
View
3  LoveSeat.Interfaces/IRepository.cs
@@ -1,6 +1,7 @@
using System;
+using LoveSeat.Interfaces;
-namespace LoveSeat.Repository
+namespace LoveSeat.Interfaces
{
public interface IRepository<T> where T : IBaseObject
{
View
9 LoveSeat.Interfaces/LoveSeat.Interfaces.csproj
@@ -10,8 +10,9 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LoveSeat.Interfaces</RootNamespace>
<AssemblyName>LoveSeat.Interfaces</AssemblyName>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
+ <TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -36,6 +37,12 @@
<Compile Include="IRepository.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
+ <ItemGroup>
+ <Reference Include="Newtonsoft.Json, Version=4.0.3.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Libraries\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
View
6 LoveSeat.Repository/AuditableRepository.cs
@@ -1,6 +1,6 @@
using System;
using Accounting.Domain;
-using LoveSeat.Repository;
+using LoveSeat.Interfaces;
namespace LoveSeat.Repositories
{
@@ -14,8 +14,8 @@ public override void Save(T item)
if (item.Rev == null)
item.CreatedAt = DateTime.Now;
item.LastModifiedAt = DateTime.Now;
- if (item.Id == Guid.Empty)
- item.Id = Guid.NewGuid();
+ if (item.Id == string.Empty)
+ item.Id = Guid.NewGuid().ToString();
base.Save(item);
}
}
View
6 LoveSeat.Repository/CouchRepository.cs
@@ -1,5 +1,5 @@
using System;
-using LoveSeat.Repository;
+using LoveSeat.Interfaces;
namespace LoveSeat.Repositories
{
@@ -13,8 +13,8 @@ public CouchRepository(CouchDatabase db)
public virtual void Save(T item)
{
- if (item.Id == Guid.Empty)
- item.Id = Guid.NewGuid();
+ if (item.Id == "")
+ item.Id = Guid.NewGuid().ToString();
var doc = new Document<T>(item);
db.SaveDocument(doc);
}
View
68 LoveSeat/CouchDatabase.cs
@@ -12,6 +12,8 @@ namespace LoveSeat
{
public class CouchDatabase : CouchBase, IDocumentDatabase
{
+ public IObjectSerializer ObjectSerializer = new DefaultSerializer();
+
private readonly string databaseBaseUri;
private string defaultDesignDoc = null;
internal CouchDatabase(string baseUri, string databaseName, string username, string password)
@@ -41,9 +43,10 @@ public JObject CreateDocument(string id, string jsonForDocument)
resp.GetJObject();
}
- public JObject CreateDocument(Document doc)
+ public JObject CreateDocument<T>(T doc)
{
- return CreateDocument(doc.Id, doc.ToString());
+ var serialized = ObjectSerializer.Serialize(doc);
+ return CreateDocument(serialized);
}
/// <summary>
/// Creates a document when you intend for Couch to generate the id for you.
@@ -72,9 +75,9 @@ public Document GetDocument(string id)
if (resp.StatusCode==HttpStatusCode.NotFound) return null;
return resp.GetCouchDocument();
}
- public T GetDocument<T>(Guid id , IObjectSerializer<T> objectSerializer)
+ public T GetDocument<T>(Guid id , IObjectSerializer objectSerializer)
{
- return GetDocument(id.ToString(), objectSerializer);
+ return GetDocument<T>(id.ToString(), objectSerializer);
}
public T GetDocument<T>(Guid id)
{
@@ -82,13 +85,13 @@ public T GetDocument<T>(Guid id)
}
public T GetDocument<T>(string id)
{
- return GetDocument(id, new ObjectSerializer<T>());
+ return GetDocument<T>(id, ObjectSerializer);
}
- public T GetDocument<T>(string id, IObjectSerializer<T> objectSerializer)
+ public T GetDocument<T>(string id, IObjectSerializer objectSerializer)
{
var resp = GetRequest(databaseBaseUri + "/" + id).Get().Json().GetResponse();
if (resp.StatusCode == HttpStatusCode.NotFound) return default(T);
- return objectSerializer.Deserialize(resp.GetResponseString());
+ return objectSerializer.Deserialize<T>(resp.GetResponseString());
}
/// <summary>
/// Adds an attachment to a document. If revision is not specified then the most recent will be fetched and used. Warning: if you need document update conflicts to occur please use the method that specifies the revision
@@ -213,6 +216,15 @@ public void SetDefaultDesignDoc(string designDoc)
{
this.defaultDesignDoc = designDoc;
}
+
+ private ViewResult<T> ProcessGenericResults<T>(string uri, ViewOptions options) {
+ CouchRequest req = GetRequest(options, uri);
+ var resp = req.GetResponse();
+ if (resp.StatusCode == HttpStatusCode.BadRequest) {
+ throw new CouchException(req.GetRequest(), resp, resp.GetResponseString() + "\n" + req.GetRequest().RequestUri);
+ }
+ return new ViewResult<T>(resp, req.GetRequest(), ObjectSerializer);
+ }
/// <summary>
/// Gets the results of the view using any and all parameters
/// </summary>
@@ -223,7 +235,7 @@ public void SetDefaultDesignDoc(string designDoc)
public ViewResult<T> View<T>(string viewName, ViewOptions options, string designDoc)
{
var uri = databaseBaseUri + "/_design/" + designDoc + "/_view/" + viewName;
- return ProcessGenericResults<T>(uri, options, new ObjectSerializer<T>());
+ return ProcessGenericResults<T>(uri, options);
}
/// <summary>
/// Allows you to specify options and uses the defaultDesignDoc Specified.
@@ -237,19 +249,7 @@ public ViewResult<T> View<T>(string viewName, ViewOptions options)
ThrowDesignDocException();
return View<T>(viewName, options, defaultDesignDoc);
}
- /// <summary>
- /// Allows you to override the objectSerializer and use the Default Design Doc settings.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="viewName"></param>
- /// <param name="options"></param>
- /// <param name="objectSerializer"></param>
- /// <returns></returns>
- public ViewResult<T> View<T>(string viewName, ViewOptions options, IObjectSerializer<T> objectSerializer)
- {
- ThrowDesignDocException();
- return View<T>(viewName, options, defaultDesignDoc, objectSerializer);
- }
+
public ViewResult View(string viewName, ViewOptions options, string designDoc)
{
var uri = databaseBaseUri + "/_design/" + designDoc + "/_view/" + viewName;
@@ -262,32 +262,6 @@ public ViewResult View(string viewName, ViewOptions options)
var uri = databaseBaseUri + "/_design/" + this.defaultDesignDoc + "/_view/" + viewName;
return ProcessResults(uri, options);
}
-
-
- /// <summary>
- /// Don't use this overload unless you intend to override the default ObjectSerialization behavior.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="viewName"></param>
- /// <param name="options"></param>
- /// <param name="designDoc"></param>
- /// <param name="objectSerializer">Only needed unless you'd like to override the default behavior of the serializer</param>
- /// <returns></returns>
- public ViewResult<T> View<T>(string viewName, ViewOptions options, string designDoc, IObjectSerializer<T> objectSerializer)
- {
- var uri = databaseBaseUri + "/_design/" + designDoc + "/_view/" + viewName;
- return ProcessGenericResults<T>(uri, options, objectSerializer);
- }
- private ViewResult<T> ProcessGenericResults<T>(string uri, ViewOptions options, IObjectSerializer<T> objectSerializer)
- {
- CouchRequest req = GetRequest(options, uri);
- var resp = req.GetResponse();
- if (resp.StatusCode == HttpStatusCode.BadRequest)
- {
- throw new CouchException(req.GetRequest(), resp, resp.GetResponseString() + "\n" + req.GetRequest().RequestUri );
- }
- return new ViewResult<T>(resp, req.GetRequest(), objectSerializer);
- }
private ViewResult ProcessResults(string uri, ViewOptions options)
{
CouchRequest req = GetRequest(options, uri);
View
17 LoveSeat/Document.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using LoveSeat.Interfaces;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -8,23 +9,27 @@ namespace LoveSeat
{
public class Document<T> : Document
{
- private static IObjectSerializer<T> objectSerializer = new ObjectSerializer<T>();
+ private static IObjectSerializer objectSerializer = new DefaultSerializer();
- public Document(T obj) : base(objectSerializer.Serialize(obj)) {
+ public Document(T obj) : base(objectSerializer.Serialize<T>(obj)) {
}
- public Document(T obj, IObjectSerializer<T> objectSerializer) : base(objectSerializer.Serialize(obj))
+ public Document(T obj, IObjectSerializer objectSerializer) : base(objectSerializer.Serialize<T>(obj))
{
}
}
- public class Document : JObject
+
+
+ public class Document : JObject, IBaseObject
{
[JsonProperty("_id")]
public string Id { get; set; }
-
+
[JsonProperty("_rev")]
public string Rev { get; set; }
-
+
+ public string Type { get; private set; }
+
protected Document()
{
}
View
27 LoveSeat/Interfaces/IDocumentDatabase.cs
@@ -15,7 +15,7 @@ public interface IDocumentDatabase
/// <returns>The status from CouchDb as a JObject</returns>
JObject CreateDocument(string id, string jsonForDocument);
- JObject CreateDocument(Document doc);
+ JObject CreateDocument<T>(T doc);
/// <summary>
/// Creates a document when you intend for Couch to generate the id for you.
@@ -34,8 +34,6 @@ public interface IDocumentDatabase
Document GetDocument(string id);
T GetDocument<T>(string id);
- T GetDocument<T>(string id, IObjectSerializer<T> objectSerializer);
-
/// <summary>
/// Adds an attachment to a document. If revision is not specified then the most recent will be fetched and used. Warning: if you need document update conflicts to occur please use the method that specifies the revision
/// </summary>
@@ -80,17 +78,6 @@ public interface IDocumentDatabase
ViewResult<T> View<T>(string viewName, ViewOptions options, string designDoc);
/// <summary>
- /// Don't use this overload unless you intend to override the default ObjectSerialization behavior.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="viewName"></param>
- /// <param name="options"></param>
- /// <param name="designDoc"></param>
- /// <param name="objectSerializer">Only needed unless you'd like to override the default behavior of the serializer</param>
- /// <returns></returns>
- ViewResult<T> View<T>(string viewName, ViewOptions options, string designDoc, IObjectSerializer<T> objectSerializer);
-
- /// <summary>
/// Gets all the documents in the database using the _all_docs uri
/// </summary>
/// <returns></returns>
@@ -115,17 +102,7 @@ public interface IDocumentDatabase
/// <returns></returns>
ViewResult<T> View<T>(string viewName, ViewOptions options);
- /// <summary>
- /// Allows you to override the objectSerializer and use the Default Design Doc settings.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="viewName"></param>
- /// <param name="options"></param>
- /// <param name="objectSerializer"></param>
- /// <returns></returns>
- ViewResult<T> View<T>(string viewName, ViewOptions options, IObjectSerializer<T> objectSerializer);
-
- T GetDocument<T>(Guid id , IObjectSerializer<T> objectSerializer);
+ T GetDocument<T>(Guid id , IObjectSerializer objectSerializer);
T GetDocument<T>(Guid id);
string Show (string showName, string docId);
IListResult List(string listName, string viewName, ViewOptions options, string designDoc);
View
7 LoveSeat/LoveSeat.csproj
@@ -110,7 +110,12 @@
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
- <ItemGroup />
+ <ItemGroup>
+ <ProjectReference Include="..\LoveSeat.Interfaces\LoveSeat.Interfaces.csproj">
+ <Project>{18833FC5-9145-451D-82D4-41A1886B0BE7}</Project>
+ <Name>LoveSeat.Interfaces</Name>
+ </ProjectReference>
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
View
23 LoveSeat/ObjectSerializer.cs
@@ -1,32 +1,33 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
namespace LoveSeat
{
- public interface IObjectSerializer<T>
+ public interface IObjectSerializer
{
- T Deserialize(string json);
- string Serialize(object obj);
- }
- public class ObjectSerializer<T> : IObjectSerializer<T>
+ T Deserialize<T>(string json);
+ string Serialize<T>(T obj);
+ }
+ public class DefaultSerializer : IObjectSerializer
{
protected readonly JsonSerializerSettings settings;
- public ObjectSerializer()
- {
+ public DefaultSerializer() {
settings = new JsonSerializerSettings();
var converters = new List<JsonConverter> { new IsoDateTimeConverter() };
settings.Converters = converters;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
- settings.NullValueHandling = NullValueHandling.Include;
+ settings.NullValueHandling = NullValueHandling.Ignore;
}
- public virtual T Deserialize(string json)
+ public T Deserialize<T>(string json)
{
return JsonConvert.DeserializeObject<T>(json, settings);
}
- public virtual string Serialize(object obj)
+
+ public string Serialize<T>(T obj)
{
return JsonConvert.SerializeObject(obj, Formatting.Indented, settings);
}
View
8 LoveSeat/ViewResult.cs
@@ -12,9 +12,9 @@ namespace LoveSeat
{
public class ViewResult<T> : ViewResult
{
- private readonly IObjectSerializer<T> objectSerializer = null;
+ private readonly IObjectSerializer objectSerializer = null;
private CouchDictionary<T> dict = null;
- public ViewResult(HttpWebResponse response, HttpWebRequest request, IObjectSerializer<T> objectSerializer)
+ public ViewResult(HttpWebResponse response, HttpWebRequest request, IObjectSerializer objectSerializer)
: base(response, request)
{
this.objectSerializer = objectSerializer;
@@ -29,7 +29,7 @@ public CouchDictionary<T> Dictionary
dict = new CouchDictionary<T>();
foreach (var row in this.Rows)
{
- dict.Add(row.Value<JToken>("key").ToString(Formatting.None), objectSerializer.Deserialize(row.Value<string>("value")));
+ dict.Add(row.Value<JToken>("key").ToString(Formatting.None), objectSerializer.Deserialize<T>(row.Value<string>("value")));
}
return dict;
}
@@ -43,7 +43,7 @@ public IEnumerable<T> Items
{
throw new InvalidOperationException("ObjectSerializer must be set in order to use the generic view.");
}
- return this.RawValues.Select(item => objectSerializer.Deserialize(item));
+ return this.RawValues.Select(item => objectSerializer.Deserialize<T>(item));
}
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.