Skip to content

Commit

Permalink
#371 Segregate example models.
Browse files Browse the repository at this point in the history
  • Loading branch information
adamjstone committed Sep 3, 2020
1 parent 92b5ca5 commit 9d8d76c
Show file tree
Hide file tree
Showing 65 changed files with 2,321 additions and 706 deletions.
1 change: 1 addition & 0 deletions en-US_User.dic
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ foof
foofoo
foreach
foundational
getters
Gitter
Glyphicons
Halflings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ protected override void OnModelCreating(IConfiguration applicationConfiguration,
})
.Entity<UserRoleModel>(entityType =>
{
return;
entityType.HasMany<UserRoleAssignmentModel>().WithOne(entity => entity.UserRole).HasForeignKey(entity => entity.UserRoleIdentifier);
})
.Entity<UserRoleAssignmentModel>(entityType =>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// =================================================================================================================================
// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
// =================================================================================================================================

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
using AssociatedDomainModel = RapidField.SolidInstruments.Example.Domain.Models.User.DomainModel;

namespace RapidField.SolidInstruments.Example.Domain.Models.User
{
/// <summary>
/// Represents a user.
/// </summary>
/// <remarks>
/// This is the data declaration for a concrete aggregate data access model. Aggregate models expose the full schema for a model
/// group and are appropriate for use in a system of record or in any context in which detail-level information is needed. Data
/// access models are in-memory representations of data entities and are used to perform data access operations. The following
/// are guidelines for use of this declaration.
/// - DO declare data properties with public getters and setters.
/// - DO decorate data properties with <see cref="ColumnAttribute" />, <see cref="DataMemberAttribute" />.
/// - DO decorate data properties with other data annotations (eg. <see cref="RequiredAttribute" />), as needed.
/// - DO NOT specify class inheritance or interface implementation(s).
/// - DO NOT decorate the class with attributes.
/// - DO NOT declare constructors.
/// - DO NOT declare computed properties or domain logic methods.
/// - DO NOT declare navigation properties.
/// </remarks>
public sealed partial class AggregateDataAccessModel
{
/// <summary>
/// Gets or sets the hashed password for the current <see cref="AggregateDataAccessModel" />.
/// </summary>
[Column]
[DataMember]
[Required]
[StringLength(AssociatedDomainModel.PasswordHashValueMaximumLength)]
public String PasswordHash
{
get;
set;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// =================================================================================================================================
// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
// =================================================================================================================================

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Runtime.Serialization;
using UserRoleAssignmentModel = RapidField.SolidInstruments.Example.Domain.Models.UserRoleAssignment.AggregateDataAccessModel;

namespace RapidField.SolidInstruments.Example.Domain.Models.User
{
/// <summary>
/// Represents a user.
/// </summary>
/// <remarks>
/// This is the navigation declaration for a concrete aggregate data access model. Aggregate models expose the full schema for a
/// model group and are appropriate for use in a system of record or in any context in which detail-level information is needed.
/// Data access models are in-memory representations of data entities and are used to perform data access operations. The
/// following are guidelines for use of this declaration.
/// - DO declare public standard navigation properties as concrete domain models.
/// - DO declare public inverse collection navigation properties as <see cref="ICollection{T}" /> of concrete domain models.
/// - DO expose getters and setters for standard navigation properties.
/// - DO expose getters (but not setters) for inverse collection navigation properties.
/// - DO lazily initialize inverse navigation collections.
/// - DO decorate standard navigation properties with <see cref="ForeignKeyAttribute" />.
/// - DO decorate standard navigation properties with <see cref="IgnoreDataMemberAttribute" />.
/// - DO decorate inverse collection navigation properties with <see cref="DataMemberAttribute" />.
/// - DO NOT specify class inheritance or interface implementation(s).
/// - DO NOT decorate the class with attributes.
/// - DO NOT declare constructors.
/// - DO NOT declare data fields or properties.
/// - DO NOT declare computed properties or domain logic methods.
/// </remarks>
public sealed partial class AggregateDataAccessModel
{
/// <summary>
/// Gets a collection of user roles which are assigned to the current <see cref="AggregateDataAccessModel" />.
/// </summary>
[DataMember]
public ICollection<UserRoleAssignmentModel> UserRoleAssignments
{
get
{
if (UserRoleAssignmentsList is null)
{
UserRoleAssignmentsList = new List<UserRoleAssignmentModel>();
}

return UserRoleAssignmentsList;
}
}

/// <summary>
/// Represents a lazily-initialized collection of user roles which are assigned to the current
/// <see cref="AggregateDataAccessModel" />.
/// </summary>
/// <remarks>
/// Lazy initialization is used for collections because <see cref="DataContractSerializer" /> cannot initialize collections
/// without public setters.
/// </remarks>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[IgnoreDataMember]
private List<UserRoleAssignmentModel> UserRoleAssignmentsList;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,33 @@
// =================================================================================================================================

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Runtime.Serialization;
using AssociatedDomainModel = RapidField.SolidInstruments.Example.Domain.Models.User.DomainModel;
using UserRoleAssignmentModel = RapidField.SolidInstruments.Example.Domain.Models.UserRoleAssignment.AggregateDataAccessModel;

namespace RapidField.SolidInstruments.Example.Domain.Models.User
{
/// <summary>
/// Represents a user.
/// </summary>
/// <remarks>
/// This is the root declaration for a concrete aggregate data access model. Aggregate models expose the full schema for a model
/// group and are appropriate for use in a system of record or in any context in which detail-level information is needed. Data
/// access models are in-memory representations of data entities and are used to perform data access operations. The following
/// are guidelines for use of this declaration.
/// - DO specify class inheritance and interface implementation(s).
/// - DO derive this class (inherit) from <see cref="ValueDataAccessModel" />.
/// - DO implement <see cref="IAggregateModel" />.
/// - DO decorate the class with <see cref="DataContractAttribute" /> and <see cref="TableAttribute" />.
/// - DO specify a custom, unique data contract name and custom, unique table name.
/// - DO declare a public, parameterless constructor.
/// - DO NOT declare data fields or properties.
/// - DO NOT declare computed properties or domain logic methods.
/// - DO NOT declare navigation properties.
/// </remarks>
[DataContract(Name = DataContractName)]
[Table(TableName)]
public sealed class AggregateDataAccessModel : ValueDataAccessModel, IAggregateModel
public sealed partial class AggregateDataAccessModel : ValueDataAccessModel, IAggregateModel
{
/// <summary>
/// Initializes a new instance of the <see cref="AggregateDataAccessModel" /> class.
Expand All @@ -29,36 +40,6 @@ public AggregateDataAccessModel()
return;
}

/// <summary>
/// Gets or sets the hashed password for the current <see cref="AggregateDataAccessModel" />.
/// </summary>
[Column]
[DataMember]
[Required]
[StringLength(AssociatedDomainModel.PasswordHashValueMaximumLength)]
public String PasswordHash
{
get;
set;
}

/// <summary>
/// Gets a collection of user roles which are assigned to the current <see cref="AggregateDataAccessModel" />.
/// </summary>
[DataMember]
public ICollection<UserRoleAssignmentModel> UserRoleAssignments
{
get
{
if (UserRoleAssignmentsValue is null)
{
UserRoleAssignmentsValue = new List<UserRoleAssignmentModel>();
}

return UserRoleAssignmentsValue;
}
}

/// <summary>
/// Represents the name that is used when representing this type as a database entity.
/// </summary>
Expand All @@ -70,12 +51,5 @@ public ICollection<UserRoleAssignmentModel> UserRoleAssignments
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private const String DataContractName = TableName + nameof(AggregateDataAccessModel);

/// <summary>
/// Represents a collection of user roles which are assigned to the current <see cref="AggregateDataAccessModel" />.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[IgnoreDataMember]
private List<UserRoleAssignmentModel> UserRoleAssignmentsValue;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// =================================================================================================================================
// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
// =================================================================================================================================

using RapidField.SolidInstruments.Core;
using RapidField.SolidInstruments.Core.ArgumentValidation;
using System;
using System.Diagnostics;
using System.Runtime.Serialization;

namespace RapidField.SolidInstruments.Example.Domain.Models.User
{
/// <summary>
/// Represents a user.
/// </summary>
/// <remarks>
/// This is the data declaration for a concrete aggregate domain model. Aggregate models expose the full schema for a model
/// group and are appropriate for use in any context in which detail-level information is needed. Domain models represent domain
/// constructs and define their characteristics and behavior. The following are guidelines for use of this declaration.
/// - DO declare data properties with public getters and setters.
/// - DO decorate data properties with <see cref="DataMemberAttribute" />.
/// - DO add validation logic to data property setters to enforce state validity, as needed.
/// - DO NOT specify class inheritance or interface implementation(s).
/// - DO NOT decorate the class with attributes.
/// - DO NOT declare constructors.
/// - DO NOT declare computed properties or domain logic methods.
/// - DO NOT declare navigation properties.
/// </remarks>
public sealed partial class DomainModel
{
/// <summary>
/// Gets or sets the email address of the current <see cref="DomainModel" />.
/// </summary>
/// <exception cref="ArgumentEmptyException">
/// <see cref="EmailAddress" /> is empty.
/// </exception>
/// <exception cref="ArgumentNullException">
/// <see cref="EmailAddress" /> is <see langword="null" />.
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <see cref="EmailAddress" /> is too long.
/// </exception>
[DataMember]
public String EmailAddress
{
get => EmailAddressValue;
set => EmailAddressValue = value.RejectIf().IsNullOrEmpty(nameof(EmailAddress)).OrIf().LengthIsGreaterThan(EmailAddressValueMaximumLength, nameof(EmailAddress));
}

/// <summary>
/// Gets or sets the name of the current <see cref="DomainModel" />.
/// </summary>
/// <exception cref="ArgumentEmptyException">
/// <see cref="Name" /> is empty.
/// </exception>
/// <exception cref="ArgumentNullException">
/// <see cref="Name" /> is <see langword="null" />.
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <see cref="Name" /> is too long.
/// </exception>
[DataMember]
public String Name
{
get => NameValue;
set => NameValue = value.RejectIf().IsNullOrEmpty(nameof(Name)).OrIf().LengthIsGreaterThan(EmailAddressValueMaximumLength, nameof(Name));
}

/// <summary>
/// Gets or sets the hashed password for the current <see cref="DomainModel" />.
/// </summary>
/// <exception cref="ArgumentEmptyException">
/// <see cref="PasswordHash" /> is empty.
/// </exception>
/// <exception cref="ArgumentNullException">
/// <see cref="PasswordHash" /> is <see langword="null" />.
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <see cref="PasswordHash" /> is too long.
/// </exception>
[DataMember]
public String PasswordHash
{
get => PasswordHashValue;
set => PasswordHashValue = value.RejectIf().IsNullOrEmpty(nameof(PasswordHash)).OrIf().LengthIsGreaterThan(PasswordHashValueMaximumLength, nameof(PasswordHash));
}

/// <summary>
/// Represents the maximum email address string length for <see cref="DomainModel" /> instances.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal const Int32 EmailAddressValueMaximumLength = 320;

/// <summary>
/// Represents the maximum name string length for <see cref="DomainModel" /> instances.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal const Int32 NameValueMaximumLength = 89;

/// <summary>
/// Represents the maximum hashed password string length for <see cref="DomainModel" /> instances.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal const Int32 PasswordHashValueMaximumLength = 89;

/// <summary>
/// Represents the email address for the current <see cref="DomainModel" />.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[IgnoreDataMember]
private String EmailAddressValue;

/// <summary>
/// Represents the name of the current <see cref="DomainModel" />.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[IgnoreDataMember]
private String NameValue;

/// <summary>
/// Represents the hashed password for the current <see cref="DomainModel" />.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[IgnoreDataMember]
private String PasswordHashValue;
}
}
Loading

0 comments on commit 9d8d76c

Please sign in to comment.