Permalink
Browse files

Chapter 7

  • Loading branch information...
1 parent 3d9de3a commit d6a3b9f56e685c90f4eb53cab9d0da588cf6531a @jchadwick jchadwick committed Nov 3, 2012
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+
+namespace Ebuy.DataAccess
+{
+ public interface IRepository : IDisposable
+ {
+ void Add<TModel>(TModel instance) where TModel : class, IEntity;
+ void Add<TModel>(IEnumerable<TModel> instances) where TModel : class, IEntity;
+
+ IQueryable<TModel> All<TModel>(params string[] includePaths) where TModel : class, IEntity;
+
+ void Delete<TModel>(object key) where TModel : class, IEntity;
+ void Delete<TModel>(TModel instance) where TModel : class, IEntity;
+ void Delete<TModel>(Expression<Func<TModel, bool>> predicate) where TModel : class, IEntity;
+
+ TModel Single<TModel>(object key) where TModel : class, IEntity;
+ TModel Single<TModel>(Expression<Func<TModel, bool>> predicate, params string[] includePaths) where TModel : class, IEntity;
+
+ IQueryable<TModel> Query<TModel>(Expression<Func<TModel, bool>> predicate, params string[] includePaths) where TModel : class, IEntity;
+ }
+}
@@ -0,0 +1,144 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Entity.Infrastructure;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Linq.Expressions;
+
+namespace Ebuy.DataAccess
+{
+ public class Repository : IRepository
+ {
+ private readonly EbuyDataContext _context;
+ private readonly bool _isSharedContext;
+
+
+ public Repository()
+ : this(new EbuyDataContext(), false)
+ {
+ }
+
+ public Repository(EbuyDataContext context, bool isSharedContext = true)
+ {
+ Contract.Requires(context != null);
+
+ _context = context;
+ _isSharedContext = isSharedContext;
+ }
+
+
+ public void Add<TModel>(TModel instance)
+ where TModel : class, IEntity
+ {
+ Contract.Requires(instance != null);
+
+ _context.Set<TModel>().Add(instance);
+
+ if (_isSharedContext == false)
+ _context.SaveChanges();
+ }
+
+ public void Add<TModel>(IEnumerable<TModel> instances)
+ where TModel : class, IEntity
+ {
+ Contract.Requires(instances != null);
+
+ foreach (var instance in instances)
+ {
+ Add(instance);
+ }
+ }
+
+
+ public IQueryable<TModel> All<TModel>(params string[] includePaths)
+ where TModel : class, IEntity
+ {
+ return Query<TModel>(x => true, includePaths);
+ }
+
+
+ public void Dispose()
+ {
+ // If this is a shared (or null) context then
+ // we're not responsible for disposing it
+ if (_isSharedContext || _context == null)
+ return;
+
+ _context.Dispose();
+ }
+
+
+ public void Delete<TModel>(object id)
+ where TModel : class, IEntity
+ {
+ Contract.Requires(id != null);
+
+ var instance = Single<TModel>(id);
+ Delete(instance);
+ }
+
+ public void Delete<TModel>(TModel instance)
+ where TModel : class, IEntity
+ {
+ Contract.Requires(instance != null);
+
+ if (instance != null)
+ _context.Set<TModel>().Remove(instance);
+ }
+
+ public void Delete<TModel>(Expression<Func<TModel, bool>> predicate)
+ where TModel : class, IEntity
+ {
+ Contract.Requires(predicate != null);
+
+ TModel entity = Single(predicate);
+ Delete(entity);
+ }
+
+
+ public TModel Single<TModel>(object id)
+ where TModel : class, IEntity
+ {
+ Contract.Requires(id != null);
+
+ var instance = _context.Set<TModel>().Find(id);
+ return instance;
+ }
+
+ public TModel Single<TModel>(Expression<Func<TModel, bool>> predicate, params string[] includePaths)
+ where TModel : class, IEntity
+ {
+ Contract.Requires(predicate != null);
+
+ var instance = GetSetWithIncludedPaths<TModel>(includePaths).SingleOrDefault(predicate);
+ return instance;
+ }
+
+
+ public IQueryable<TModel> Query<TModel>(Expression<Func<TModel, bool>> predicate, params string[] includePaths)
+ where TModel : class, IEntity
+ {
+ Contract.Requires(predicate != null);
+
+ var items = GetSetWithIncludedPaths<TModel>(includePaths);
+
+ if (predicate != null)
+ return items.Where(predicate);
+
+ return items;
+ }
+
+
+ private DbQuery<TModel> GetSetWithIncludedPaths<TModel>(IEnumerable<string> includedPaths) where TModel : class, IEntity
+ {
+ DbQuery<TModel> items = _context.Set<TModel>();
+
+ foreach (var path in includedPaths ?? Enumerable.Empty<string>())
+ {
+ items = items.Include(path);
+ }
+
+ return items;
+ }
+ }
+}
@@ -48,8 +48,11 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="DataAccess\IRepository.cs" />
+ <Compile Include="DataAccess\Repository.cs" />
<Compile Include="Entities\Auction.cs" />
<Compile Include="DataAccess\EbuyDataContext.cs" />
+ <Compile Include="Entities\Entity.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
@@ -3,7 +3,7 @@
namespace Ebuy
{
- public class Auction
+ public class Auction : IEntity
{
public long Id { get; set; }
@@ -0,0 +1,60 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace Ebuy
+{
+ public interface IEntity
+ {
+ }
+
+ public abstract class Entity<TId> : IEntity, IEquatable<Entity<TId>>
+ where TId : struct
+ {
+ [Key]
+ public virtual TId Id
+ {
+ get
+ {
+ if (_id == null && typeof(TId) == typeof(Guid))
+ _id = Guid.NewGuid();
+
+ return _id == null ? default(TId) : (TId)_id;
+ }
+ protected set { _id = value; }
+ }
+ private object _id;
+
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != typeof(Entity<TId>)) return false;
+ return Equals((Entity<TId>)obj);
+ }
+
+ public bool Equals(Entity<TId> other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ if (other.GetType() != GetType()) return false;
+
+ return other.Id.Equals(Id);
+ }
+
+ public override int GetHashCode()
+ {
+ return Id.GetHashCode();
+ }
+
+ public static bool operator ==(Entity<TId> left, Entity<TId> right)
+ {
+ return Equals(left, right);
+ }
+
+ public static bool operator !=(Entity<TId> left, Entity<TId> right)
+ {
+ return !Equals(left, right);
+ }
+ }
+}
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net.Http.Formatting;
+using System.Net.Http.Headers;
+
+namespace Ebuy.Website.Api
+{
+ public class AuctionCsvFormatter : BufferedMediaTypeFormatter
+ {
+ public AuctionCsvFormatter()
+ {
+ SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));
+ }
+
+ public override bool CanWriteType(Type type)
+ {
+ if (type == typeof(Auction))
+ {
+ return true;
+ }
+ else
+ {
+ Type enumerableType = typeof(IEnumerable<Auction>);
+ return enumerableType.IsAssignableFrom(type);
+ }
+ }
+
+ public override bool CanReadType(Type type)
+ {
+ return false;
+ }
+
+ public override void WriteToStream(Type type, object value, Stream stream, System.Net.Http.HttpContent content)
+ {
+ var source = value as IEnumerable<Auction>;
+ if (source != null)
+ {
+ foreach (var item in source)
+ {
+ WriteItem(item, stream);
+ }
+ }
+ else
+ {
+ var item = value as Auction;
+ if (item != null)
+ {
+ WriteItem(item, stream);
+ }
+ }
+ }
+
+ private void WriteItem(Auction item, Stream stream)
+ {
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("{0},{1},{2}",
+ Encode(item.Title),
+ Encode(item.Description),
+ Encode(item.CurrentPrice));
+ writer.Flush();
+ }
+
+ static readonly char[] _specialChars = new char[] { ',', '\n', '\r', '"' };
+ private string Encode(object o)
+ {
+ string result = "";
+ if (o != null)
+ {
+ string data = o.ToString();
+ if (data.IndexOfAny(_specialChars) != -1)
+ {
+ result = String.Format("\"{0}\"", data.Replace("\"", "\"\""));
+ }
+ }
+ return result;
+ }
+ }
+}
@@ -0,0 +1,54 @@
+using System;
+using System.Linq;
+using System.Web.Http;
+using AutoMapper;
+using Ebuy.DataAccess;
+
+namespace Ebuy.Website.Api
+{
+ public class AuctionsDataController : ApiController
+ {
+ private readonly IRepository _repository;
+
+ public AuctionsDataController(IRepository repository)
+ {
+ _repository = repository;
+ }
+
+ public IQueryable<Auction> Get()
+ {
+ return _repository.All<Auction>().AsQueryable();
+ }
+
+ [CustomExceptionFilter]
+ public Auction Get(string id)
+ {
+ var result = _repository.Single<Auction>(id);
+
+ if (result == null)
+ {
+ throw new Exception("Item not Found!");
+ }
+
+ return result;
+ }
+ public void Post(Auction auction)
+ {
+ _repository.Add<Auction>(auction);
+ }
+
+ public void Put(string id, Auction auction)
+ {
+ var currentAuction = _repository.Single<Auction>(id);
+ if (currentAuction != null)
+ {
+ Mapper.DynamicMap(auction, currentAuction);
+ }
+ }
+
+ public void Delete(string id)
+ {
+ _repository.Delete<Auction>(id);
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit d6a3b9f

Please sign in to comment.