Commit f6250567 authored by Steve Smith's avatar Steve Smith

Fleshing out ValueObject

parent ac6fbd12
using System;
namespace CleanArchitecture.Core.SharedKernel
{
// source: https://github.com/jhewlett/ValueObject
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class IgnoreMemberAttribute : Attribute
{
}
}
\ No newline at end of file
namespace CleanArchitecture.Core.SharedKernel using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace CleanArchitecture.Core.SharedKernel
{ {
public abstract class ValueObject // source: https://github.com/jhewlett/ValueObject
public abstract class ValueObject : IEquatable<ValueObject>
{ {
private List<PropertyInfo> properties;
private List<FieldInfo> fields;
public static bool operator ==(ValueObject obj1, ValueObject obj2)
{
if (object.Equals(obj1, null))
{
if (object.Equals(obj2, null))
{
return true;
}
return false;
}
return obj1.Equals(obj2);
}
public static bool operator !=(ValueObject obj1, ValueObject obj2)
{
return !(obj1 == obj2);
}
public bool Equals(ValueObject obj)
{
return Equals(obj as object);
}
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType()) return false;
return GetProperties().All(p => PropertiesAreEqual(obj, p))
&& GetFields().All(f => FieldsAreEqual(obj, f));
}
private bool PropertiesAreEqual(object obj, PropertyInfo p)
{
return object.Equals(p.GetValue(this, null), p.GetValue(obj, null));
}
private bool FieldsAreEqual(object obj, FieldInfo f)
{
return object.Equals(f.GetValue(this), f.GetValue(obj));
}
private IEnumerable<PropertyInfo> GetProperties()
{
if (this.properties == null)
{
this.properties = GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.GetCustomAttribute(typeof(IgnoreMemberAttribute)) == null)
.ToList();
// Not available in Core
// !Attribute.IsDefined(p, typeof(IgnoreMemberAttribute))).ToList();
}
return this.properties;
}
private IEnumerable<FieldInfo> GetFields()
{
if (this.fields == null)
{
this.fields = GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.GetCustomAttribute(typeof(IgnoreMemberAttribute)) == null)
.ToList();
}
return this.fields;
}
public override int GetHashCode()
{
unchecked //allow overflow
{
int hash = 17;
foreach (var prop in GetProperties())
{
var value = prop.GetValue(this, null);
hash = HashValue(hash, value);
}
foreach (var field in GetFields())
{
var value = field.GetValue(this);
hash = HashValue(hash, value);
}
return hash;
}
}
private int HashValue(int seed, object value)
{
var currentHash = value != null
? value.GetHashCode()
: 0;
return seed * 23 + currentHash;
}
} }
} }
\ No newline at end of file
{ {
"version": "1.0.0-*", "version": "1.0.0-*",
"dependencies": { "dependencies": {
"NETStandard.Library": "1.6.0" "NETStandard.Library": "1.6.0",
"System.Reflection.TypeExtensions": "4.1.0"
}, },
"frameworks": { "frameworks": {
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CleanArchitecture.Core.Entities;
using CleanArchitecture.Core.Interfaces;
using Microsoft.AspNetCore.Mvc;
namespace CleanArchitecture.Web.Api
{
[Route("api/[controller]")]
public class ToDoItemsController : Controller
{
private readonly IRepository<ToDoItem> _todoRepository;
public ToDoItemsController(IRepository<ToDoItem> todoRepository)
{
_todoRepository = todoRepository;
}
// GET: api/ToDoItems
[HttpGet]
public IActionResult List()
{
var items = _todoRepository.List();
return Ok(items);
}
// GET: api/ToDoItems
[HttpGet("{id:int}")]
public IActionResult GetById(int id)
{
var items = _todoRepository.GetById(id);
return Ok(items);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment