Browse Source

Documented Value Objects

pull/6075/head
Halil İbrahim Kalkan 5 years ago
parent
commit
24b2e16ce2
  1. 2
      docs/en/Domain-Driven-Design.md
  2. 76
      docs/en/Value-Objects.md
  3. 3
      docs/en/docs-nav.json
  4. 36
      framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Values/Address.cs
  5. 30
      framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Values/ValueObject_Tests.cs

2
docs/en/Domain-Driven-Design.md

@ -27,9 +27,9 @@ See the following documents to learn what ABP Framework provides to you to imple
* **Domain Layer**
* [Entities & Aggregate Roots](Entities.md)
* Value Objects
* [Repositories](Repositories.md)
* [Domain Services](Domain-Services.md)
* [Value Objects](Value-Objects.md)
* Specifications
* **Application Layer**
* [Application Services](Application-Services.md)

76
docs/en/Value-Objects.md

@ -1,3 +1,75 @@
## Value Objects
# Value Objects
TODO
> An object that represents a descriptive aspect of the domain with no conceptual identity is called a VALUE OBJECT.
>
> (Eric Evans)
Two [Entities](Entities.md) with the same properties but with different `Id`s are considered as different entities. However, Value Objects have no `Id`s and they are considered as equals if they have the same property values.
## The ValueObject Class
`ValueObject` is an abstract class that can be inherited to create a Value Object class.
**Example: An Address class**
````csharp
public class Address : ValueObject
{
public Guid CityId { get; private set; }
public string Street { get; private set; }
public int Number { get; private set; }
private Address()
{
}
public Address(
Guid cityId,
string street,
int number)
{
CityId = cityId;
Street = street;
Number = number;
}
protected override IEnumerable<object> GetAtomicValues()
{
yield return Street;
yield return CityId;
yield return Number;
}
}
````
* A Value Object class must implement the `GetAtomicValues()` method to return the primitive values.
### ValueEquals
`ValueObject.ValueEquals(...)` method is used to check if two Value Objects are equals.
**Example: Check if two addresses are equals**
````csharp
Address address1 = ...
Address address2 = ...
if (address1.ValueEquals(address2)) //Check equality
{
...
}
````
## Best Practices
Here are some best practices when using Value Objects:
- Design a value object as **immutable** (like the Address above) if there is not a good reason for designing it as mutable.
- The properties that make up a Value Object should form a conceptual whole. For example, CityId, Street and Number shouldn't be separate properties of a Person entity. This also makes the Person entity simpler.
## See Also
* [Entities](Entities.md)

3
docs/en/docs-nav.json

@ -340,7 +340,8 @@
"path": "Entities.md"
},
{
"text": "Value Objects"
"text": "Value Objects",
"path": "Value-Objects.md"
},
{
"text": "Repositories",

36
framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Values/Address.cs

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.Domain.Values
{
public class Address : ValueObject
{
public Guid CityId { get; }
public string Street { get; }
public int Number { get; }
private Address()
{
}
public Address(
Guid cityId,
string street,
int number)
{
CityId = cityId;
Street = street;
Number = number;
}
//Requires to implement this method to return properties.
protected override IEnumerable<object> GetAtomicValues()
{
yield return Street;
yield return CityId;
yield return Number;
}
}
}

30
framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Values/ValueObject_Tests.cs

@ -0,0 +1,30 @@
using System;
using Shouldly;
using Xunit;
namespace Volo.Abp.Domain.Values
{
public class ValueObject_Tests
{
[Fact]
public void ValueObjects_With_Same_Properties_Should_Be_Equals()
{
var cityId = Guid.NewGuid();
var address1 = new Address(cityId, "Baris Manco", 42);
var address2 = new Address(cityId, "Baris Manco", 42);
address1.ValueEquals(address2).ShouldBeTrue();
}
[Fact]
public void ValueObjects_With_Different_Properties_Should_Not_Be_Equals()
{
var cityId = Guid.NewGuid();
var address1 = new Address(cityId, "Baris Manco", 42);
var address2 = new Address(cityId, "Baris Manco", 42);
address1.ValueEquals(address2).ShouldBeFalse();
}
}
}
Loading…
Cancel
Save