I'm trying to utilize automapper for some conversions between two classes.
I have four classes - two parent classes where both have a child collection of the remaining two.
public class ParentA
{
public IEnumerable<ChildA> Children{get;set;}
}
public class ChildA
{
public ParentA Parent{get;set;
}
public class ParentB
{
public IEnumerable<ChildA> Children{get;set;}
}
public class ChildB
{
public ParentA Parent{get;set;
}
I need to ensure that the Parent property is set for both collections before mapping occurs. For the source object I do the following:
CreateMap<ParentA, ParentB>()
.BeforeMap((a, b) =>
{
foreach (var entry in a.Entries)
entry.Parent = a;
})
However, I do not know how to do the same for the destination object. I need to check the parent due to some conditional mapping and value resolution.
Related
Take the following example code:
public abstract class ElementBase
{
}
public class ElementOne : ElementBase
{
}
public class ElementTwo : ElementBase
{
[XmlElement("element-one", typeof(ElementOne))]
[XmlElement("element-two", typeof(ElementTwo))]
public ElementBase[] SubElements { get; set; }
}
[XmlRoot("root-element")]
public class RootElement
{
[XmlElement("element-one", typeof(ElementOne))]
[XmlElement("element-two", typeof(ElementTwo))]
public ElementBase[] SubElements { get; set;}
}
The attributes on ElementOne.SubElements and ElementTwo.SubElements need to stay in sync (i.e., attributes added to one will need to be added to the other, and arguments need to stay the same), The reason for this is that in the xml, <element-one> and elements can both appear as subelements to <root-element> and <element-two>. The elements can be in any order, and the order is important. Also, there will probably be more subelements in the future. The way it is currently coded will make maintenance tedious and error-prone because of the need to maintain two separate places for attributes.
Is there a way to have these attributes "shared" between the two properties, such that a single edit will affect them both? I tried the following:
public class CommomAttribute : Attribute
{
public XmlElementAttribute f = new XmlElementAttribute("element-one", typeof(ElementOne));
public XmlElementAttribute l = new XmlElementAttribute("element-two", typeof(ElementTwo));
}
I then replaced the redundant attributes on the above classes' properties with a single [Command]. This didn't work.
An alternative question: is there a more elegant way to solve this problem?
You can try this if you don't mind having to go one level deeper to get to you sub-element items:
public abstract class ElementBase
{
}
public class ElementOne : ElementBase
{
}
public class ElementTwo : ElementBase
{
public SubElementList SubElements { get; set; }
}
public class SubElementList
{
[XmlElement("element-one", typeof(ElementOne))]
[XmlElement("element-two", typeof(ElementTwo))]
public ElementBase[] Items { get; set; }
}
[XmlRoot("root-element")]
public class RootElement
{
public SubElementList SubElements { get; set; }
}
Off the top of my head, I'd do the following:
On the ctor of each class (One and Two), require and instance of ElementBase and keep it as a private attribute (let's say, "SyncingElement")
Modify the setter of SubElements, to sync with the instance of "SyncingElement"
This way, SubElements on both objects would have the same memory address (same instance). So, if someone get the instance of SubElements from One modifies the object at index [2] (for example), it would affect SubElements at Two as well.
I am working on an application which currently creates data entity objects from the results of a sql query. In the database 3 of the tables are very similar but have several different properties.
My initial plan was to create 3 different classes, even though each class is very similar. However when I came to create the method which returns a list of objects, I have hit a stumbling block as the return type will be different depending on which mode the application is in.
e.g.
public class A
{
public int Id {get;}
public string Name {get;}
}
public class B
{
public int Id {get;}
public string Name {get;}
public string ExtraInfo {get;}
}
public class MainScreen
{
...
this.resultsGrid.DataSource = LoadData();
}
I would prefer not to write one method to load a list of each data type.
What should the return type of LoadData() be, to allow it to be generic as possible.
What is the most elegant way of dealing with this scenario?
Thanks,
Sean
You should have inheritance to allow polymorphism, so you would have a base class that all entities included in the data binding derive from it.
Then, you can have a mid-base class to have some shared properties like Name and ID.
Base class:
public abstract class Entity
{
}
Entity with Name and ID:
public class NameAndIDEntity : Entity
{
public int Id { get; set; }
public string Name { get; set; }
}
Entity with Name, ID and ExtraInfo:
public class NameIDAndExtraEntity : NameAndIDEntity
{
public string ExtraInfo { get; set; }
}
Entity with other information (can't be derived from NameAndIDEntity), derives from Entity so it can be included in the data binding:
public class OtherInformationEntity : Entity
{
public int Age { get; set; }
}
Finally, you can make the LoadData return type Entity.
Simples!
Create a class ListItem (with properties Id and Name, I presume). In your factory class/method, make instances of that class from the records into a List and bind the datasource to the list.
Don't be scared to create specialised classes for your UI.
UPDATE: Forgot to mention. Avoid inheritance as much as possible.
First you can create an inheitance tree in your project, where base class holds a shared/common properties among set of dfferent types
Second you can retrieve from the query anonymous type and after map it to a known type by mapping them to a real type, like from Jon Skeet's blog Horrible grotty hack: returning an anonymous type instance
That means that you need by the way know which query what type returns (can not avoid that), but this can reduce amount of fraction you need to add to your code, like from example:
static class GrottyHacks
{
internal static T Cast<T>(object target, T example) //CAST TO SPECIFIED TYPE
{
return (T) target;
}
}
class CheesecakeFactory
{
static object CreateCheesecake()
{
return new { Fruit="Strawberry", Topping="Chocolate" };
}
static void Main()
{
object weaklyTyped = CreateCheesecake(); //ANONYMOUS TYPE GENERATION
var stronglyTyped = GrottyHacks.Cast(weaklyTyped,
new { Fruit="", Topping="" }); //"MAPPING"
Console.WriteLine("Cheesecake: {0} ({1})",
stronglyTyped.Fruit, stronglyTyped.Topping);
}
}
I just try to redesign my Silverlight-4 App and tried a bit around with generics.
Simply speaking, I have a tree which can contain 2 types of nodes. As a base class, I created a class that does all the "organization", like having a list of children, a parent, a method to add a child and so on:
public abstract class BaseNode<T> : INotifyPropertyChanged where T: BaseNode<T>
{
protected ObservableCollection<T> _children;
...
}
Second, I add a class that inherits from BaseNode and is the basis for all my treenodes:
public class ServiceNodeBase<T> : BaseNode<ServiceNodeBase<T>> where T : ServiceNodeBase<T>
{
public string Description { get; set; }
...
}
And finally, as I can have two different kinds of nodes, I create a class for each kind, i.e.:
public class ServiceNodeComponent<T> : ServiceNodeBase<ServiceNodeComponent<T>> where T : ServiceNodeComponent<T>
{
public HashSet<Attributes> Attributes { get; set; }
...
}
In the ServiceNodeComponent, I need a method, that scans the tree i.e. to get all the child nodes, that are of the Type ServiceNodeComponent. When parsing the tree, I need to use the parent-type of ServiceNodeComponent (ServiceNodeBase), because the child nodes can also be of the other type.
Now, I do not know how to instantiate the ServiceNodeBase-Variable.
public HashSet<ServiceNodeComponent<T>> GetAllChildComponents()
{
// declaring the container for the found Components is no problem
HashSet<ServiceNodeComponent<T>> resultList = new HashSet<ServiceNodeComponent<T>>();
// but now: how to declare the container for the ServiceBaseNodes?
HashSet<ServiceNodeBase<???>> workingList = new HashSet<ServiceNodeBase<???>>();
Any ideas, how I would implement this?
Thanks in advance,
Frank
The problem is the constraint. It would work if you change it to
public class ServiceNodeComponent<T> : ServiceNodeBase<ServiceNodeComponent<T>>
where T : ServiceNodeBase<T> {
public HashSet<ServiceNodeComponent<T>> GetAllChildComponents() {
// ...
HashSet<ServiceNodeBase<T>> workingList = new HashSet<ServiceNodeBase<T>>();
// ...
}
}
I have a Person class and two inherited classes called Parent and Child. A Parent can have n Child(s) and a Child can have n Parent(s).
What is the best way in OOD to create a reference between a Parent and a Child.
Should I create a List in each class referencing the connected Parent/Child or is there a better way?
Great question. Pure many-to-many relationships are actually quite rare, and it usually helps to introduce an intermediate object to model the relationship itself. This will prove invaluable if (when!) use cases emerge which require the capture of properties regarding the relationship (e.g. whether the child/parent relationship is natural, surrogate, adoptive, etc).
So, in addition to the Person, Parent and Child entities which you've already identified, let's introduce an object called ParentChildRelationship.
An instance of ParentChildRelationship will have a reference to exactly one Parent and One Child, and both the Parent and Child classes will hold a collection of these entities.
It's a good idea to then identify the use cases you have for working with these entities, and add appropriate helper methods to maintain the inter-object references.
In the example below I've just chosen to add a public AddChild method to the parent.
public abstract class Person
{
}
public class Parent : Person
{
private HashSet<ParentChildRelationship> _children =
new HashSet<ParentChildRelationship>();
public virtual IEnumerable<ParentChildRelationship> Children
{
get { return this._children; }
}
public virtual void AddChild(Child child, RelationshipKind relationshipKind)
{
var relationship = new ParentChildRelationship()
{
Parent = this,
Child = child,
RelationshipKind = relationshipKind
};
this._children.Add(relationship);
child.AddParent(relationship);
}
}
public class Child : Person
{
private HashSet<ParentChildRelationship> _parents =
new HashSet<ParentChildRelationship>();
public virtual IEnumerable<ParentChildRelationship> Parents
{
get { return this._parents; }
}
internal virtual void AddParent(ParentChildRelationship relationship)
{
this._parents.Add(relationship);
}
}
public class ParentChildRelationship
{
public virtual Parent Parent { get; protected internal set; }
public virtual Child Child { get; protected internal set; }
public virtual RelationshipKind RelationshipKind { get; set; }
}
public enum RelationshipKind
{
Unknown,
Natural,
Adoptive,
Surrogate,
StepParent
}
public class Person
{
Person Parent { get;set; }
IList<Person> Children { get;set; }
}
Parent can be null when you do not know the parent.
Children can be null or empty when you have no children.
Since each child is a Person, it can have a Parent or its own children.
This design, by itself, is fine until you provide more detailed use case scenarios about how it will be used or persisted.
If you can limit the direction of the association to go only one way, you will save yourself a lot of trouble (but this is not always possible).
One-way relationship:
public class Parent : Person
{
public IEnumerable<Person> Children { get; }
}
If you want to have the association going the other direction as well, you can do so too:
public class Child : Person
{
public Parent Parent { get; }
}
However, now you have a circular reference that you need to maintain, and while it's possible, it's not particularly productive.
You can often keep the association as a one-way relationship by letting the children raise events instead of explicitly referencing their parent.
As JohnIdol pointed out, a child someway down the line might become a parent. In other words DON'T make Parent and Child sub-classes of Person.
class Person
{
readonly List<Person> _children = new List<Person>(),
_parents = new List<Person>();
public IEnumerable<Person> Children
{
get { return _children.AsReadOnly(); }
}
public IEnumerable<Person> Parents
{
get { return _parents.AsReadOnly(); }
}
public void AddChild(Person child)
{
_children.Add(child);
child._parents.Add(this);
}
public void AddParent(Person parent)
{
_parents.Add(parent);
parent._children.Add(this);
}
/* And so on... */
}
I would imagine that a child can also be a parent down the line (if he gets lucky ... or unlucky, depending on points of view) so I would go with something like:
IPerson
{
string Name {get; set;}
string LastName {get; set;}
// whatever else - such as sizeOfShoe, dob, etc
}
IHaveParents
{
// might wanna limit this to a fixed size
List<IPerson> Parents {get; set;}
}
IHaveChildren
{
List<IPerson> Children {get; set;}
}
IHaveSpouse
{
IPerson Spouse {get; set;}
}
public class DudeWithParentsAndChildren : IPerson, IHaveParents, IHaveChildren, IHaveSpouse
{
public void AskMoneyToParents(){throw new Exception("Implement me!");}
public void SlapChildren(){}
private void CheatOnSpouse(){}
// some other stuff that such a dude can do i.e. GoBowling
}
And you could easily extend this any way you like when new requirements come along (trust me they will).
Update:
So in your case if you only want a Child to have Parents and the other way around you'd do something like:
public class Child : IPerson, IHaveParents
{
public void AskMoneyToParents(){throw new Exception("Implement me!");}
}
public class Parent : IPerson, IHaveChildren, IHaveSpouse
{
public void SlapChildren(){}
private void CheatOnSpouse(){}
// some other stuff that such a dude can do i.e. GoBowling
}
This way if you want to have an IHaveFriends interface you can (which basically forces the implementer to expose a list of IPersons as a property named Friends). If you don't need it don't do it, but the fact that you can easily do it just adding an interface an everything else stays the same means you've got a pretty decent extensible model (not necessarily the best, you know what I mean).
I've a question regarding enforcing a business rule via a specification pattern. Consider the following example:
public class Parent
{
private ICollection<Child> children;
public ReadOnlyCollection Children { get; }
public void AddChild(Child child)
{
child.Parent = this;
children.Add(child);
}
}
public class Child
{
internal Parent Parent
{
get;
set;
}
public DateTime ValidFrom;
public DateTime ValidTo;
public Child()
{
}
}
The business rule should enforce that there cannot be a child in the collection which validity period intersects with another.
For that I would like to implement a specification that is then be used to throw an exception if an invalid child is added AND as well can be used to check whether the rule will be violated BEFORE adding the child.
Like:
public class ChildValiditySpecification
{
bool IsSatisfiedBy(Child child)
{
return child.Parent.Children.Where(<validityIntersectsCondition here>).Count > 0;
}
}
But in this example the child accesses the parent. And to me that doesnt seem that correct. That parent might not exist when the child has not been added to the parent yet. How would you implement it?
public class Parent {
private List<Child> children;
public ICollection<Child> Children {
get { return children.AsReadOnly(); }
}
public void AddChild(Child child) {
if (!child.IsSatisfiedBy(this)) throw new Exception();
child.Parent = this;
children.Add(child);
}
}
public class Child {
internal Parent Parent { get; set; }
public DateTime ValidFrom;
public DateTime ValidTo;
public bool IsSatisfiedBy(Parent parent) { // can also be used before calling parent.AddChild
return parent.Children.All(c => !Overlaps(c));
}
bool Overlaps(Child c) {
return ValidFrom <= c.ValidTo && c.ValidFrom <= ValidTo;
}
}
UPDATE:
But of course, the real power of the specification pattern is when you can plug in and combine different rules. You can have an interface like this (possibly with a better name):
public interface ISpecification {
bool IsSatisfiedBy(Parent parent, Child candidate);
}
And then use it like this on Parent:
public class Parent {
List<Child> children = new List<Child>();
ISpecification childValiditySpec;
public Parent(ISpecification childValiditySpec) {
this.childValiditySpec = childValiditySpec;
}
public ICollection<Child> Children {
get { return children.AsReadOnly(); }
}
public bool IsSatisfiedBy(Child child) {
return childValiditySpec.IsSatisfiedBy(this, child);
}
public void AddChild(Child child) {
if (!IsSatisfiedBy(child)) throw new Exception();
child.Parent = this;
children.Add(child);
}
}
Child would be simple:
public class Child {
internal Parent Parent { get; set; }
public DateTime ValidFrom;
public DateTime ValidTo;
}
And you could implement multiple specifications, or composite specifications. This is the one from your example:
public class NonOverlappingChildSpec : ISpecification {
public bool IsSatisfiedBy(Parent parent, Child candidate) {
return parent.Children.All(child => !Overlaps(child, candidate));
}
bool Overlaps(Child c1, Child c2) {
return c1.ValidFrom <= c2.ValidTo && c2.ValidFrom <= c1.ValidTo;
}
}
Note that it makes more sense to make Child's public data immutable (only set through the constructor) so that no instance can have its data changed in a way that would invalidate a Parent.
Also, consider encapsulating the date range in a specialized abstraction.
I think the Parent should probably do the validation. So in the parent you might have a canBeParentOf(Child) method. This method would also be called at the top of your AddChild method--then the addChild method throws an exception if canBeParentOf fails, but canBeParentOf itself does not throw an exception.
Now, if you want to use "Validator" classes to implement canBeParentOf, that would be fantastic. You might have a method like validator.validateRelationship(Parent, Child). Then any parent could hold a collection of validators so that there could be multiple conditions preventing a parent/child relationship. canBeParentOf would just iterate over the validators calling each one for the child being added--as in validator.canBeParentOf(this, child);--any false would cause canBeParentOf to return a false.
If the conditions for validating are always the same for every possible parent/child, then they can either be coded directly into canBeParentOf, or the validators collection can be static.
An aside: The back-link from child to parent should probably be changed so that it can only be set once (a second call to the set throws an exception). This will A) Prevent your child from getting into an invalid state after it's been added and B) detect an attempt to add it to two different parents. In other words: Make your objects as close to immutable as possible. (Unless changing it to different parents is possible). Adding a child to multiple parents is obviously not possible (from your data model)
Would you not have an If statement to check that a parent was not null and if so return false?
You are trying to guard against Child being in an invalid state. Either
use the builder pattern to create fully populated Parent types so that everything you expose to the consumer is always in a valid state
remove the reference to the Parent completely
have Parent create all instances of Child so this can never occur
The latter case might look (something) like this (in Java):
public class DateRangeHolder {
private final NavigableSet<DateRange> ranges = new TreeSet<DateRange>();
public void add(Date from, Date to) {
DateRange range = new DateRange(this, from, to);
if (ranges.contains(range)) throw new IllegalArgumentException();
DateRange lower = ranges.lower(range);
validate(range, lower);
validate(range, ranges.higher(lower == null ? range : lower));
ranges.add(range);
}
private void validate(DateRange range, DateRange against) {
if (against != null && range.intersects(against)) {
throw new IllegalArgumentException();
}
}
public static class DateRange implements Comparable<DateRange> {
// implementation elided
}
}